Файл VFS чем открыть

Обновлено: 21.11.2024

В этой статье описывается уровень переносимости ОС SQLite или «VFS» — модуль в нижней части стека реализации SQLite, обеспечивающий переносимость между операционными системами.

Внутреннюю организацию библиотеки SQLite можно рассматривать как стек модулей, показанный справа. Компоненты Tokenizer, Parser и Code Generator используются для обработки операторов SQL и преобразования их в исполняемые программы на языке виртуальной машины или в байт-коде. Грубо говоря, эти три верхних слоя реализуют sqlite3_prepare_v2(). Байт-код, сгенерированный тремя верхними уровнями, представляет собой подготовленный оператор. Модуль виртуальной машины отвечает за выполнение байт-кода оператора SQL. Модуль B-Tree организует файл базы данных в несколько хранилищ ключей/значений с упорядоченными ключами и логарифмической производительностью. Модуль пейджера отвечает за загрузку страниц файла базы данных в память, за реализацию и контроль транзакций, а также за создание и поддержку файлов журналов, которые предотвращают повреждение базы данных после сбоя или сбоя питания. Интерфейс ОС — это тонкая абстракция, предоставляющая общий набор подпрограмм для адаптации SQLite для работы в разных операционных системах. Грубо говоря, нижние четыре слоя реализуют sqlite3_step().

Эта статья посвящена нижнему слою.

Интерфейс ОС, также называемый «VFS», — это то, что делает SQLite переносимым между операционными системами. Всякий раз, когда каким-либо другим модулям SQLite необходимо взаимодействовать с операционной системой, они вызывают методы в VFS. Затем VFS вызывает операционный код, необходимый для удовлетворения запроса. Следовательно, перенос SQLite на новую операционную систему — это просто вопрос написания нового уровня интерфейса ОС или «VFS».

Стандартное исходное дерево SQLite содержит встроенные VFS для Unix и Windows. Альтернативные VFS можно добавить во время запуска или во время выполнения с помощью интерфейса sqlite3_vfs_register().

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

3.1. Стандартные VFS Unix

Сборки Unix поставляются с несколькими встроенными VFS. VFS по умолчанию для unix называется «unix» и используется в большинстве приложений. Другие VFS, которые можно найти в Unix (в зависимости от параметров времени компиляции), включают:

unix-dotfile — использует блокировку точечного файла, а не рекомендательную блокировку POSIX.

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

unix-none — все операции блокировки файлов не выполняются.

unix-namedsem — использует именованные семафоры для блокировки файлов. Только VXWorks.

Различные VFS Unix различаются только тем, как они обрабатывают блокировку файлов — они имеют большую часть своей реализации, и все они расположены в одном и том же исходном файле SQLite: os_unix.c. Обратите внимание, что, за исключением «unix» и «unix-excl», различные VFS Unix используют несовместимые реализации блокировки. Если два процесса обращаются к одной и той же базе данных SQLite, используя разные Unix VFS, они могут не видеть блокировки друг друга и в конечном итоге могут мешать друг другу, что приводит к повреждению базы данных. В частности, VFS «unix-none» вообще не блокирует и легко приведет к повреждению базы данных, если используется двумя или более подключениями к базе данных одновременно. Программистам рекомендуется использовать только "unix" или "unix-excl", если нет веских причин делать иначе.

3.2. Стандартные VFS для Windows

Сборки Windows также поставляются с несколькими встроенными VFS. Windows VFS по умолчанию называется «win32» и используется в большинстве приложений. Другие VFS, которые можно найти в сборках Windows, включают:

win32-longpath — аналогично «win32», за исключением того, что пути могут иметь длину до 65 534 байт, тогда как в «win32» максимальная длина пути составляет 1040 байт.

win32-none — все операции по блокировке файлов не выполняются.

win32-longpath-none – комбинация "win32-longpath" и "win32-none" – поддерживаются длинные пути, а все операции блокировки не выполняются.

Как и в случае с unix, большая часть кода для различных Windows VFS используется совместно.

3.3. Выбор используемой VFS

Всегда существует одна VFS, которая является VFS по умолчанию. В Unix-системах VFS «unix» используется по умолчанию, а в Windows — «win32». Если не предпринимать никаких других действий, новые подключения к базе данных будут использовать VFS по умолчанию.

VFS по умолчанию можно изменить, зарегистрировав или перерегистрировав VFS с помощью интерфейса sqlite3_vfs_register() со вторым параметром, равным 1.Следовательно, если процесс (unix) хочет всегда использовать VFS "unix-nolock" вместо "unix", будет работать следующий код:

Альтернативный VFS также можно указать в качестве 4-го параметра функции sqlite3_open_v2(). Например:

Виртуальная файловая система, указанная в URI, имеет наивысший приоритет. После этого идет VFS, указанная в качестве четвертого аргумента sqlite3_open_v2(). VFS по умолчанию используется, если не указано иное VFS.

3.4. Прокладки VFS

С точки зрения верхних уровней стека SQLite каждый открытый файл базы данных использует ровно одну VFS. Но на практике конкретная VFS может быть просто тонкой оболочкой другой VFS, выполняющей настоящую работу. Мы называем оболочку VFS "прокладкой".

Простым примером прокладки является VFS "vfstrace". Это VFS (реализованная в исходном файле test_vfstrace.c), которая записывает сообщение, связанное с каждым вызовом метода VFS, в файл журнала, а затем передает управление другой VFS для выполнения фактической работы.

3.5. Другие примеры VFS

В общедоступном дереве исходного кода SQLite доступны другие реализации VFS:

appendvfs.c — эта VFS позволяет добавлять базу данных SQLite в конец какого-либо другого файла. Это можно использовать, например, для добавления базы данных SQLite в конец исполняемого файла, чтобы при запуске он мог легко найти добавленную базу данных. Оболочка командной строки будет использовать эту VFS, если она запущена с параметром --append, а ее команда .archive будет использовать ее с флагом --append.

test_demovfs.c — этот файл реализует очень простую VFS под названием «demo», которая использует функции POSIX, такие как open(), read(), write(), fsync(), close(), fsync(), sleep( ), время() и так далее. Эта VFS работает только в unix-системах. Но он не предназначен для замены стандартной «unix» VFS, используемой по умолчанию на платформах unix. «Демонстрационная» VFS намеренно сделана очень простой, чтобы ее можно было использовать в качестве учебного пособия или шаблона для создания других VFS или для переноса SQLite на новые операционные системы.

test_quota.c — этот файл реализует прокладку под названием «quota», которая обеспечивает совокупные ограничения размера файла для набора файлов базы данных. Вспомогательный интерфейс используется для определения «групп квот». Группа квот — это набор файлов (файлов базы данных, журналов и временных файлов), все имена которых соответствуют шаблону GLOB. Сумма размеров всех файлов в каждой группе квот отслеживается, и если эта сумма превышает порог, определенный для группы квот, вызывается функция обратного вызова. Этот обратный вызов может либо увеличить порог, либо привести к сбою операции, которая превысила бы квоту, с ошибкой SQLITE_FULL. Одно из применений этой оболочки — принудительное ограничение ресурсов для баз данных приложений в Firefox.

test_multiplex.c — этот файл реализует прокладку, которая позволяет файлам базы данных превышать максимальный размер файла базовой файловой системы. Эта оболочка представляет собой интерфейс для шести верхних уровней SQLite, из-за чего создается впечатление, что используются очень большие файлы, хотя на самом деле каждый такой большой файл разбит на множество более мелких файлов в базовой системе. Эта прокладка использовалась, например, для того, чтобы позволить базам данных увеличиваться больше чем на 2 гигабайта в файловых системах FAT16.

test_onefile.c — этот файл реализует демонстрационную VFS с именем «fs», которая показывает, как можно использовать SQLite на встроенном устройстве, на котором отсутствует файловая система. Контент записывается непосредственно на основной носитель. VFS, полученная из этого демонстрационного кода, может использоваться гаджетом с ограниченным объемом флэш-памяти, чтобы заставить SQLite вести себя как файловая система для флэш-памяти на устройстве.

test_journal.c — этот файл реализует прокладку, используемую во время тестирования SQLite, которая проверяет, что база данных и журнал отката записываются в правильном порядке и «синхронизируются» в соответствующее время, чтобы гарантировать, что база данных может восстановиться после отключения питания. потерять жестко сбрасываются в любое время. Оболочка проверяет несколько инвариантов работы баз данных и журналов отката и выдает исключения, если какой-либо из этих инвариантов нарушается. Эти инварианты, в свою очередь, гарантируют, что базу данных всегда можно восстановить. Запуск большого набора тестов с использованием этой оболочки обеспечивает дополнительную уверенность в том, что базы данных SQLite не будут повреждены в результате неожиданных сбоев питания или перезагрузки устройства.

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

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

Новая VFS реализуется путем создания подклассов трех объектов:

Объект sqlite3_vfs определяет имя VFS и основные методы, реализующие интерфейс к операционной системе, такие как проверка существования файлов, удаление файлов, создание файлов и открытие, а также чтение и/или запись, преобразование имен файлов. в их каноническую форму. Объект sqlite3_vfs также содержит методы для получения рандома от операционной системы, для приостановки процесса (перехода в спящий режим) и для определения текущей даты и времени.

Объект sqlite3_file представляет собой открытый файл. Метод xOpen sqlite3_vfs создает объект sqlite3_file при открытии файла. sqlite3_file отслеживает состояние файла во время его открытия.

Объект sqlite3_io_methods содержит методы, используемые для взаимодействия с открытым файлом. Каждый sqlite3_file содержит указатель на объект sqlite3_io_methods, соответствующий файлу, который он представляет. Объект sqlite3_io_methods содержит методы для выполнения таких действий, как чтение и запись из файла, усечение файла, сброс любых изменений в постоянное хранилище, определение размера файла, блокировка и разблокировка файла, а также закрытие файла и уничтожить объект sqlite3_file.

Написание кода для новой VFS включает в себя создание подкласса для объекта sqlite3_vfs, а затем регистрацию этого объекта VFS с помощью вызова sqlite3_vfs_register(). Реализация VFS также предоставляет подклассы для sqlite3_file и sqlite3_io_methods, но эти объекты не регистрируются непосредственно в SQLite. Вместо этого объект sqlite3_file возвращается из метода xOpen sqlite3_vfs, а объект sqlite3_file указывает на экземпляр объекта sqlite3_io_methods.

У вас возникли проблемы с открытием файла VFS или вам просто интересно, что он содержит? Мы объясним, для чего используются эти файлы, и покажем вам программное обеспечение, которое, как мы знаем, может открывать или иным образом обрабатывать ваши файлы.

Что такое файл VFS?

Файл .VFS – это файл виртуальной файловой системы Gnome.

Файлы с расширением .vfs чаще всего связаны с виртуальными файловыми системами. В случае виртуальной файловой системы Gnome, также известной как GnomeVFS, это уровень абстракции файловой системы, который находится между приложениями и реальными файловыми системами, такими как Windows NTFS, цифровые камеры или WebDAV.

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

Как открыть файлы VFS

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

Хотя мы сами еще не проверяли приложения, наши пользователи предложили 5 различных открывателей VFS, которые вы найдете в списке ниже.

Последнее обновление: 17 марта 2022 г.

Предложить другой формат файла с расширением VFS

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

Различные приложения, использующие файлы с этим расширением

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

< td >VideoMotionPro
Средство просмотра фотографий Picasa Отправлено пользователем
< /td>Adobe Acrobat Отправлено пользователем
Dragon UnPACKer Отправлено пользователем< /td>
VF Show Отправлено пользователем
Отправлено пользователем

Не уверены, какой тип файла вы пытаетесь открыть? Попробуйте наш новый анализатор файлов. Это бесплатный инструмент, который может идентифицировать более 11 000 различных типов файлов — скорее всего, и ваши! Это поможет вам найти программное обеспечение, которое может обрабатывать файлы определенного типа. Загрузите анализатор файлов здесь.

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

Расширение файла VFS

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

Операционные системы

Что такое файл VFS?

Файл .VFS – это файл игры. Этот формат используется играми из серии НЛО. Сериал также известен как X-COM, в основном в США. Файл не предназначен для открытия вручную и необходим для запуска игры.Игры были выпущены на различных платформах, от Amiga через ПК до консолей Playstation 3 и Xbox 360. Игры обычно сочетали элементы широкой стратегии с задачей защиты человечества от космических захватчиков.

Как открыть файл VFS?

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

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

Шаг 1. Установите монтирование

Первый шаг — проверить, установлена ​​ли на компьютере программа монтирования. Для этого введите название mount в системный поисковик. Если у нас нет этой программы, то стоит ее установить, так как она поможет вам автоматически связать файл VFS с mount. Ниже приведен список программ, поддерживающих файл VFS.

Программы для открытия файла VFS

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

НЛО: Послесвет

НЛО: последствия

НЛО: Афтершок

Распаковщик дракона

монтирование
Шаг 2. Создайте ассоциацию монтирования с файлами VFS

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

Шаг 3. Обновите монтирование до последней версии

Если же после привязки mount с UFO Game Archive Format все же остались проблемы, следует обновить программу до последней версии.

Шаг 4. Проверьте наличие следующих проблем с файлом VFS

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

Файл VFS пуст или неполный.

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

Файл VFS заражен

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

Это более старая версия файла

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

Файл поврежден

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

Файл VFS зашифрован

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

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

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

Файл VFS используется

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

Виртуальные файловые системы — это волшебная абстракция, которая делает возможной философию Linux «все есть файл».

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

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

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

Если мы можем открыть(), прочитать() и записать(), это будет файл, как показано в этом сеансе консоли.

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

Дополнительные ресурсы по Linux

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

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

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

VFS — это «прослойка» между системными вызовами и реализаторами конкретных файловых_операций, таких как ext4 и procfs. После этого функции file_operations могут взаимодействовать либо с драйверами конкретных устройств, либо со средствами доступа к памяти. tmpfs , devtmpfs и cgroups не используют file_operations, а обращаются к памяти напрямую.

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

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

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

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

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

/proc и /sys

Помимо /tmp, наиболее знакомыми большинству пользователей 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 составляет большую часть знаменитого «стабильного ABI ядра для пользовательского пространства», который никто и ни при каких обстоятельствах не может «сломать». Это не означает, что файлы в sysfs являются статическими, что противоречит подсчету ссылок на изменчивые объекты.

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

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

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

Самый простой способ узнать, как ядро ​​​​управляет файлами sysfs, — посмотреть его в действии, а самый простой способ посмотреть на ARM64 или x86_64 — использовать eBPF. eBPF (расширенный пакетный фильтр Беркли) состоит из виртуальной машины, работающей внутри ядра, которую привилегированные пользователи могут запрашивать из командной строки. Исходный код ядра сообщает читателю, что ядро ​​может делать; запуск инструментов eBPF в загруженной системе вместо этого показывает, что на самом деле делает ядро.

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

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

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

Посмотрите с помощью eBPF, что происходит в /sys при вставке USB-накопителя, на простых и сложных примерах.

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

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

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

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

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

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

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

Создание корневой файловой системы только для чтения требует дополнительных усилий от разработчиков встраиваемых систем, и именно здесь на помощь приходит VFS. Linux требует, чтобы файлы в /var были доступны для записи, и, кроме того, многие популярные приложения, запускаемые встроенными системами, создать конфигурационные dot-файлы в $HOME. Одним из решений для файлов конфигурации в домашнем каталоге обычно является их предварительное создание и встраивание в rootfs. Для /var один из подходов состоит в том, чтобы смонтировать его на отдельном доступном для записи разделе, в то время как сам / монтируется как доступный только для чтения. Еще одна популярная альтернатива — использование привязных или накладных креплений.

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

Running 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 в каталоге fs/ верхнего уровня представляют собой его реализацию виртуальных файловых систем, которые представляют собой слой-оболочку, обеспечивающий широкое и относительно простое взаимодействие популярных файловых систем и устройств хранения. Связывание и наложение монтирования через пространства имен Linux — это магия VFS, которая делает возможным использование контейнеров и корневых файловых систем только для чтения. В сочетании с изучением исходного кода средство ядра eBPF и его интерфейс bcc делают исследование ядра проще, чем когда-либо прежде.

Большое спасибо Аккане Пек и Майклу Игеру за комментарии и исправления.

Элисон Чайкен представит виртуальные файловые системы: зачем они нам нужны и как они работают на 17-й ежегодной выставке Linux в Южной Калифорнии (SCaLE 17x), которая пройдет с 7 по 10 марта в Пасадене, Калифорния.

ВФС

Содержание

Введение

Виртуальная файловая система (VFS) — это не файловая система на диске или сетевая файловая система. Таким образом, это не структура данных (например, ReiserFS, NTFS или FAT) и не сетевой протокол (например, NFS). На самом деле это просто абстракция, которую многие операционные системы предоставляют приложениям, так что пусть вас не пугает это название.

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

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

Устранение неоднозначности базовой семантики VFS

В частности, VFS обеспечивает единый путь доступа и подсистему для группы файловых систем одного типа. На сегодняшний день существует три распространенных типа файловых систем: иерархическая (наиболее распространенная), файловая система на основе тегов и файловая система базы данных.

Модели VFS

Индексировано (*-DOS/NT)

Модель VFS, используемая в *-DOS и Windows NT, назначает букву алфавита каждой доступной файловой системе на машине. Этот тип VFS наиболее прост в реализации, но он ограничен 26 смонтированными файловыми системами и может становиться все более и более сложным по мере добавления функций, поэтому вместо этого вы можете использовать числа. Когда запрашивается файл, VFS проверяет, на каком диске находится файл, а затем передает запрос соответствующему драйверу.

Список точек монтирования

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

График узла (Unix)

Модель VFS, которая может быть очень эффективной, — это Node Graph. Эта модель поддерживает граф узлов файловой системы, которые могут представлять файл, папку, точку монтирования или файл другого типа. Граф узлов может перемещаться быстрее, чем список, но страдает от проблем со сложностью и, если требуется большое количество узлов, может занимать большой объем памяти.

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

Компрометация

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

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

Абстракция файлов

Одной из наиболее важных частей ОС является создание файловой абстракции, то есть скрытие базовой структуры файловой системы и структуры секторов от приложения. Обычно это реализуется системными вызовами open, read, write и close (обозначает как POSIX, так и Windows).

Открытие файла

Эта функция отвечает за поиск или создание контекста (inode или vnode VFS) для данного имени файла. Обычно это означает перебор вышеупомянутых узлов VFS в памяти, и, если файл не найден, обратитесь к списку монтирования (см. выше), драйверу файловой системы и драйверу хранилища, чтобы получить необходимые метаданные (в терминологии POSIX, структура fstat) . Системный вызов open возвращает идентификатор, который связывает открытый файл с этим контекстом. Этот идентификатор может быть глобально уникальным (например, FCB) или локальным для процесса (целое число, типичное для UNIX-подобных систем). Указанный контекст должен содержать такую ​​информацию, как

  • устройство хранения, на котором находится открытый файл
  • структура, описывающая, какие сектора принадлежат этому файлу в хранилище (или простая ссылка на инод)
  • размер файла
  • позиция в файле (смещение поиска)
  • режим доступа к файлу (чтение/запись)

Здесь желательно создать еще один уровень абстракции и разделить контекст на два. Одна структура, описывающая всю информацию с точки зрения FS (vnode), и другая структура с точки зрения приложения (структура открытого файла, ссылающаяся только на vnode). Преимущество здесь в том, что вы можете вести счетчик количества открытых потоков во vnode, который вам понадобится позже. Помните, что несколько процессов могут открыть один и тот же файл для чтения, поэтому вы не можете напрямую указать позицию файла во vnode. Размещаете ли вы этот список открытых файлов в адресном пространстве процесса или в VFS, решать вам. Но vnodes должны храниться в центральном месте в VFS, иначе вы не сможете избежать условий гонки и реализовать правильную блокировку файлов.

Чтение или письмо

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

<р>1. Используя позицию файла и информацию о размере файла в контексте, он должен определить, сколько секторов необходимо (зависит от размера логического сектора ФС). Возможно, что позиция в файле больше или равна размеру файла, поэтому ответ равен нулю. В этом случае VFS должна предоставить способ указать состояние EOF. Если позиция и размер файла больше, чем размер файла, аргумент размера должен быть уменьшен. Обратите внимание, что позиция файла может не находиться на границе сектора, и даже чтение 2 байтов может распространяться на несколько секторов.

<р>2. Используя информацию о файловом хранилище в контексте, VFS должна создать список адресов секторов для устройства. Это можно сделать унифицированным (независимым от FS) способом, хотя файловые системы имеют тенденцию использовать очень разные алгоритмы распределения (кластеры FAT, непрямое дерево inode, экстенты и т. д.), поэтому в большинстве реализаций VFS эта задача делегируется драйверу файловой системы. Не забывайте, что файловые системы используют логические сектора.

<р>3. Список логических секторов необходимо преобразовать в список физических секторов. Обычно это означает добавление начального сектора раздела, на котором находится файловая система, но также может означать большее или меньшее количество элементов в списке, если размер логического сектора и размер физического сектора различаются. Короче говоря, VFS (зная характеристики базового устройства хранения) должна преобразовать список LSN в список LBA.

<р>4. Теперь, когда известен список физических секторов, VFS может использовать вызовы readsector в соответствующем драйвере диска. Устройство хранения хранится в контексте (предоставляя параметр устройства для вызова), а дерево устройств ядра должно указывать, какой драйвер использовать.

<р>5. Как только сектора находятся в памяти, VFS необходимо скопировать их содержимое в буфер считывателя. Если позиция в файле не кратна размеру сектора, то первый сектор будет начинаться с дополнительных данных, которые VFS должна пропустить. Если позиция в файле плюс размер чтения не кратны размеру сектора, то в последнем секторе есть лишние данные, которые VFS должна отбросить.

<р>6. VFS должна выполнять служебные операции в контексте. Обычно это означает настройку положения файла и тому подобное.

<р>7. VFS теперь может уведомлять читателя (в POSIX это означает активировать заблокированный процесс).

Запись имеет аналогичные шаги, но здесь VFS должна выделить логические сектора (или кластеры, полосы и т. д., что бы файловая система ни использовала для выделения), вызывая драйвер файловой системы. При записи VFS должна считывать как минимум первый и последний сектор, поскольку они могут содержать дополнительные данные, см. шаг 5 выше.

Закрытие файла

Наконец, функция закрытия отвечает за сброс любых изменений файла в хранилище (в случае записи), обновляя метаданные файловой системы. Обычно это означает вызов драйвера файловой системы. И последнее, но не менее важное: освободите память, выделенную для записи списка открытых файлов.Если у вас есть отдельный vnode + список открытых файлов (так и должно быть), тогда VFS должна уменьшить счетчик открытых потоков vnode, а если он равен нулю, также освободить vnode.

Читайте также: