- Какую фс выбрать для виртуальной машины?
- Описание VFS Виртуальной Файловой Системы Linux
- Введение
- Кэш записей каталога / Directory Entry Cache (dcache)
- Объект Inode / The Inode Object
- Объект File / The File Object
- Регистрация и монтирование файловой системы
- struct file_system_type
- Объект super_block
- struct super_operations
- Объект Inode
- struct inode_operations
- Объект Адресное Пространство
- Обработка ошибок в течении writeback
- struct address_space_operations
- Объект Файл
- struct file_operations
- Directory Entry Cache (dcache)
- struct dentry_operations
- Directory Entry Cache API
- Mount Options
- Parsing options
- Showing options
- Виртуальные файловые системы в Linux: зачем они нужны и как они работают? Часть 2
Какую фс выбрать для виртуальной машины?
Поскольку у меня основная рабочая ОС это Gentoo, а в Windows я уже и забыл, когда загружал комп, то решил раздел под виндой снести и поставить виртуальную машину (ну если бы не работа,- написание веб-приложений под .net , то и не заморачивался насчет винды вообще).
С таким железом я думаю VirtualBox справится.
А теперь по сути вопроса: т.к. раздел с виндой я буду форматировать, то какую файловую систему выбрать для вирт. жесткого диска? — Естественно, интересует быстродействие. Мои соображения- это xfs, т.к. жд виртуальный и будет 500-700 Гб отведено под это дело.
Может будут другие соображения?
С таким железом я думаю VirtualBox справится.
Зачем оно нужно когда есть qemu-kvm?
Тебе же десктопные задачи на десктопном железе — чего ерундой заниматься — дефолт устроит.
А USB qemu понимает? Лет 7 назад, когда пробовал, то не он не смог увидеть флэшку.
Ну, может еще usb-звуковую карту подключу.
В смысле «дефолт»? — Вы говорите о ext3 ?
А если насчет того, чтобы оставить винду- уже не хочу.
Оптимизирована для common use-cases, как говорится.
Естественно, интересует быстродействие.
Источник
Описание VFS Виртуальной Файловой Системы Linux
Мой неполный перевод Overview of the Linux Virtual File System. Некоторые моменты, по различным причинам, я пока не понимаю, поэтому кое-что привожу в оригинале, как повод для дальнейших размышлений. Другие же моменты, как мне кажется, я понимаю, поэтому дополнил их некоторой информацией.
Введение
Виртуальная Файловая Система (называемая также Коммутатором Виртуальной Файловой Системы) является программным слоем, который предоставляет программам, выполняющимся в пользовательском пространстве, интерфейс взаимодействия с файловой системой. VFS-коммутатор также реализует в ядре Linux уровень абстракции для унификации подключения к нему разнообразных файловых систем.
Системные вызовы VFS open(2) , stat(2) , read(2) , write(2) , chmod(2) и так далее, вызываются из контекста работающего процесса. Filesystem locking описана в Documentation/filesystems/locking.rst . (VFS system calls open(2), stat(2), read(2), write(2), chmod(2) and so on are called from a process context. Filesystem locking is described in the document Documentation/filesystems/locking.rst.)
Кэш записей каталога / Directory Entry Cache (dcache)
VFS обеспечивает системные вызовы open(2) , stat(2) , chmod(2) и другие похожие. Аргумент pathname , который передаётся на вход этим системным вызовам, используется VFS-системой для поиска вхождений в кэше записей каталога (называемым также dentry cache, или ещё короче dcache). Это обеспечивает сверхбыстрый механизм трансляции pathname (filename) в определённый dentry . Кэш записей каталога необходим только для увеличения производительности, поэтому он хранится в оперативной памяти и никогда не записывается на диск.
Dentry-кэш предназначен для обзора всего файлового пространства. А так как большинство компьютеров не могут вместить все записи dentry в оперативную память, то некоторое количество записей в dentry-кэше может отсутствовать. Поэтому, иногда в процессе сопоставления частей pathname с соответствующими dentry, VFS-коммутатору, возможно, придётся заодно создать некоторое количество dentry, и только после этого загрузить требуемый inode.
Объект Inode / The Inode Object
Отдельный dentry обычно указывает на inode, который является специальной структурой файловой системы, описывающей её файлы-объекты. Объект inode предоставляет различные сведения о файле ( man 2 stat ). В частности:
- st_dev – id устройства, содержащего файл;
- st_ino – номер этой inode в таблице inodes;
- st_mode – тип объекта ( man 7 inode ):
- обычный файл с данными;
- directory;
- block device;
- .
- st_nlink – количество жёстких ссылок (имён файлов) на этот inode.
Объект inode не содержит имени файла! Так как в пределах одной файловой системы (POSIX) на один файл может ссылаться больше одной именованной жёсткой ссылки, то имя файла не сохраняется в inode . Вместо этого, в файлах-каталогах (тип directory), в списке содержимого данного каталога, создаётся запись: имя файла (то есть имя жёсткой ссылки) — номер inode. Отсюда следует, что при обнулении поля st_nlink в структуре какого-либо inode , соответствующие блоки файловой системы будут помечены свободными и файл можно считать удалённым.
Inodes могут находиться на дисках (на файловых системах блочных устройств), либо в оперативной памяти (на псевдо-файловых системах). Inodes, находящиеся на дисках, при необходимости копируются в оперативную память, а при каких-либо в них изменениях, обновлённая копия записывается обратно на диск. Несколько dentry могут указывать на один inode (в случае жёстких ссылок и тому подобное).
Для поиска какого-либо inode необходимо, чтобы для его родительского inode-каталога, VFS вызвала метод lookup() . Этот метод установлен конкретной реализацией ФС, к которой относится требуемый inode. (This method is installed by the specific filesystem implementation that the inode lives in.) С момента получения VFS-коммутатором dentry (а следовательно и соответствующего inode), мы можем делать с ним всякие скучные вещи, типа открыть файл посредством системного вызова open(2) , или получить данные inode через stat(2) . Из пользовательского пространства системный вызов stat(2) работает довольно просто: как только VFS заимел соответствующий dentry, он передаёт данные из inode обратно в userspace (The stat(2) operation is fairly simple: once the VFS has the dentry, it peeks at the inode data and passes some of it back to userspace.).
Объект File / The File Object
Открытие какого-либо файла требует ещё одной операции: выделение файловой структуры (это реализация файловых дескрипторов на стороне ядра). Свеже выделенная файловая структура инициализируется с указателем на соответствующий dentry и на набор файловых операций функций-членов. (The freshly allocated file structure is initialized with a pointer to the dentry and a set of file operation member functions.) Они берутся из сведений, содержащихся в соответствующей inode. Применяемый к файлу метод open() вызывается тогда, как только конкретная реализация файловой системы сможет сделать это. Вы можете видеть, что это ещё одна функция выполняемая VFS-коммутатором. Файловая структура помещается в таблицу дескрипторов файлов для вызывающего процесса.
Чтение, запись и закрытие файла (и другие подобные операции VFS) осуществляются с помощью соответствующих методов, перечисленных в подходящей к требуемому файлу файловой структуре, каковая структура становится доступной из пространства пользователя через использование конкретного файлового дескриптора. Dentry остаётся в использовании, пока файл открыт, что, в свою очередь, означает, что VFS inode остаётся в использовании.
Регистрация и монтирование файловой системы
Процедура регистрации типа файловой системы в ядре Linux, и процедура отмены регистрации, используют следующие функции API:
Передающийся struct file_system_type описывает вашу ФС. Когда запрашивается монтирование тома какой-либо ФС к каталогу в вашем пространстве имён, то VFS вызывет подходящий метод монтирования для конкретной ФС. Новый vfsmount, ссылающийся на дерево, возвращаемое ->mount(), будет подсоединён к точке монтирования, так что когда в процессе разбора pathname будет достигнута точка монтирования, то будет совершён переход внутрь vfsmount, на его корень.
Вы можете узнать о всех зарегистрированных в ядре типах файловых систем в файле /proc/filesystems /
struct file_system_type
Эта структура описывает файловую систему. Начиная с kernel 2.6.39, определены следующие элементы struct :
name
— наименование типа файловой системы, например как «ext2», «iso9660», «msdos» и прочее.fs_flags
— различные флаги (то есть, FS_REQUIRES_DEV, FS_NO_DCACHE, и т.д.)mount
— метод, вызов которого производится при монтировании нового экземпляра файловой системыkill_sb
— метод, вызов которого производится при размонтировании экземпляра файловой системыowner
— для внутреннего использования VFS: в большинстве случаев вы должны инициализировать это через THIS_MODULEnext
— для внутреннего использования VFS: вы должны инициализировать это в NULLs_lock_key, s_umount_key: lockdep-specific
Метод mount() имеет следующие аргументы:
struct file_system_type *fs_type
— описывает файловую систему, частично инициализируется определённым кодом файловой системыint flags
— флаги монтированияconst char *dev_name
— монтируемое имя устройстваvoid *data
— различные опции в виде ASCII-строки, указываемые при монтировании (смотри раздел “Mount Options”)При вызове, метод mount() должен возвращать корневой dentry запрошенного дерева каталогов. Вызывающий процесс должен захватить ссылку на суперблок ФС, и суперблок должен быть заблокирован. При ошибке, метод возвращает указатель ERR_PTR (ошибка).
Аргументы соответствуют таковым из mount(2) и их интерпретация зависит от типа ФС. Например, для блочной файловой системы, dev_name интерпретируется как имя блочного устройства, и устойство это открыто, и оно содержит подходящую файловую систему, для которой метод mount() создаёт и инициализирует соответствующий struct super_block , и возвращает корневой dentry вызывающему процессу.
Объект super_block
Объект superblock представляет монтированную файловую систему.
struct super_operations
Эта структура описывает как VFS может манипулировать суперблоком вашей файловой системы. Начиная с kernel 2.6.22, определены следующие элементы:
Все методы вызываются без каких-либо удерживаемых? (being held) блокировок, если не указано иное. Это означает, что большинство методов можно безопасно блокировать. Все методы вызываются только из контекста процесса (то есть не из обработчика прерываний или ниже (bottom half)).
Объект Inode
Объект inode представляет объект внутри файловой системы.
struct inode_operations
Эта структура описывает, как VFS может манипулировать inode’ом в вашей файловой системе. Начиная с kernel 2.6.22, определены следующие элементы:
И опять, все методы вызываются без каких-либо блокировок, если не указано иное.
Объект Адресное Пространство
Объект адресное пространство используется для группирования и управления страницами в страничном кэше (page cache). Он может быть использован для отслеживания страниц в файле и отслеживания отображения секция файла в адресное пространство процесса.
Обработка ошибок в течении writeback
Большинство приложений, которые буферизуют операции чтения/записи, периодически синхронизируют файл вызовом (fsync, fdatasync, msync or sync_file_range), чтобы быть уверенным, что данные в буфере сброшены обратно на устройство хранения. .
struct address_space_operations
Эта структура описывает, как VFS может манипулировать отображением файла в страничном кэше в вашей файловой системе. Определены следующие элементы структуры:
writepage
— вызывается Виртуальной Машиной для сброса черновых страниц обратно в хранилище. Это может случаться для сохранения целостности данных ( sync ), или для освобождения памяти (flush).readpage
— вызывается Виртуальной Машиной при чтении страницы из хранилища. Эта страница будет заблокирована во время вызова readpage , и должна быть разблокирована и промаркирована, как uptodate, с момента завершения чтения. Если ->readpage обнаруживает, что требуется разблокировка страницы по какой-либо причине, то он может сделать это, но вернув AOP_TRUNCATED_PAGE. В этом случае страница будет relocated, relocked и, если всё успешно будет выполнено, то вызов ->readpage будет повторён.writepages
— вызывается Виртуальной Машиной для сброса на диск всех страниц, ассоциированных с адресным пространством объекта.Объект Файл
Файловый объект представляет файл, открытый процессом. Он также известен, как файловый дескриптор (open file description) в POSIX-диалекте.
struct file_operations
Эта структура описывает, как VFS может манипулировать открытым файлом. Начиная с kernel 4.18, определены следующие элементы:
Again, all methods are called without any locks being held, unless otherwise noted.
llseek
— вызывается, когда VFS нуждается в перемещении file position indexread
— называется read(2) и относится к системным вызовам
.Directory Entry Cache (dcache)
struct dentry_operations
Эта структура описывает, как файловая система может перегружать стандартные dentry операции.
Directory Entry Cache API
There are a number of functions defined which permit a filesystem to manipulate dentries:
Mount Options
Parsing options
При монтировании или размонтировании файловой системы, передаётся строка, содержащая список опций монтирования, разделённых запятыми. Эти опции могут иметь любую из этих форм:
The header defines an API that helps parse these options. There are plenty of examples on how to use it in existing filesystems.
Showing options
Если файловая система приняла опции, то она должна определить show_options(), для показа всех актуальных текущих опций. Правила показа:
- обязаны быть показаны тех опции, значения которых отличаются от принимаемых по умолчанию;
- могут быть показаны те опции, которые включены (по умолчанию) или имеют значения по умолчанию.
Опции, внутренее используемые между маунт хэлпером и ядром (такие как дескриптор файла), или которые значимы только во время монтирования (такие, как управляющие созданием журнала), исключены от вышеоуказанных правил.
Источник
Виртуальные файловые системы в Linux: зачем они нужны и как они работают? Часть 2
Всем привет, делимся с вами второй частью публикации «Виртуальные файловые системы в Linux: зачем они нужны и как они работают?» Первую часть можно прочитать тут. Напомним, данная серия публикаций приурочена к запуску нового потока по курсу «Администратор Linux», который стартует уже совсем скоро.
Как наблюдать за VFS с помощью инструментов eBPF и bcc
Самый простой способ понять, как ядро оперирует файлами sysfs – это посмотреть за этим на практике, а самый простой способ понаблюдать за ARM64 – это использовать eBPF. eBPF (сокращение от Berkeley Packet Filter) состоит из виртуальной машины, запущенной в ядре, которую привилегированные пользователи могут запрашивать ( query ) из командной строки. Исходники ядра сообщают читателю, что может сделать ядро; запуск инструментов eBPF в загруженной системе показывает, что на самом деле делает ядро.
К счастью, начать использовать eBPF достаточно легко с помощью инструментов bcc, которые доступны в качестве пакетов из общего дистрибутива Linux и подробно задокументированы Бернардом Греггом. Инструменты bcc – это скрипты на Python с маленькими вставками кода на С, это означает, что каждый, кто знаком с обоими языками может с легкостью их модифицировать. В bcc/tools есть 80 Python скриптов, а это значит, что скорее всего разработчик или системный администратор сможет подобрать себе что-нибудь подходящее для решения задачи.
Чтобы получить хотя бы поверхностное представление о том, какую работу выполняют VFS в запущенной системе, попробуйте vfscount или vfsstat . Это покажет, допустим, что десятки вызовов vfs_open() и «его друзей» происходят буквально каждую секунду.
vfsstat.py – это скрипт на Python, со вставками С кода, который просто считает вызовы функций VFS.
Приведем более тривиальный пример и посмотрим, что бывает, когда мы вставляем USB-флеш накопитель в компьютер и его обнаруживает система.
С помощью eBPF можно посмотреть, что происходит в /sys , когда вставлен USB-флеш накопитель. Здесь показан простой и сложный пример.
В примере, показанном сверху, bcc инструмент trace.py выводит сообщение, когда запускается команда sysfs_create_files() . Мы видим, что sysfs_create_files() был запущен с помощью kworker потока в ответ на то, что флешка была вставлена, но какой файл при этом создался? Второй пример показывает всю мощь eBPF. Здесь trace.py выводит обратную трассировку ядра (kernel backtrace) (опция -K) и имя файла, который был создан sysfs_create_files() . Вставка в одиночных высказываниях – это код на С, включающий легко распознаваемую строку формата, обеспечиваемую Python скриптом, который запускает LLVM just-in-time компилятор. Эту строку он компилирует и выполняет в виртуальной машине внутри ядра. Полная сигнатура функции sysfs_create_files () должна быть воспроизведена во второй команде, чтобы строка формата могла ссылаться на один из параметров. Ошибки в этом фрагменте кода на С приводят к распознаваемым ошибкам C-компилятора. Например, если пропущен параметр -l, то вы увидите «Failed to compile BPF text.» Разработчики, которые хорошо знакомы с С и Python, найдут инструменты bcc простыми для расширения и изменения.
Когда USB-накопитель вставлен, обратная трассировка ядра покажет, что PID 7711 – это поток kworker , который создал файл «events» в sysfs . Соответственно, вызов с sysfs_remove_files() покажет, что удаление накопителя привело к удалению файла events , что соответствует общей концепции подсчета ссылок. При этом, просмотр sysfs_create_link () с eBPF во время вставки USB-накопителя покажет, что создано не менее 48 символьных ссылок.
Так в чем же смысл файла events? Использование cscope для поиска __device_add_disk(), показывает, что она вызывает disk_add_events () , и либо «media_change» , либо «eject_request» могут быть записаны в файл событий. Здесь блочный слой ядра информирует userspace о появлении и извлечении «диска». Обратите внимание, насколько информативен этот метод исследования на примере вставки USB-накопителя по сравнению с попытками выяснить, как все работает, исключительно из исходников.
Корневые файловые системы только для чтения делают возможными встроенные устройства
Конечно, никто не выключает сервер или свой компьютер, вытаскивая вилку из розетки. Но почему? А все потому что смонтированные файловые системы на физических устройствах хранения могут иметь отложенные записи, а структуры данных, записывающие их состояние, могут не синхронизироваться с записями в хранилище. Когда это случается, владельцам системы приходится ждать следующей загрузки для запуска утилиты fsck filesystem-recovery и, в худшем случае, потерять данные.
Тем не менее, все мы знаем, что многие IoT устройства, а также маршрутизаторы, термостаты и автомобили теперь работают под управлением Linux. Многие из этих устройств практически не имеют пользовательского интерфейса, и нет никакого способа выключить их «чисто». Представьте себе запуск автомобиля с разряженной батареей, когда питание управляющего устройства на Linux постоянно скачет вверх-вниз. Как получается, что система загружается без длинного fsck , когда двигатель наконец начинает работать? А ответ прост. Встроенные устройства полагаются на корневую файловую систему только для чтения (сокращенно ro-rootfs (read-only root fileystem)).
ro-rootfs предлагают множество преимуществ, которые менее очевидны, чем неподдельность. Одно из преимуществ заключается в том, что вредоносное ПО не может писать в /usr или /lib , если ни один процесс Linux не может туда писать. Другое заключается в том, что в значительной степени неизменяемая файловая система имеет решающее значение для полевой поддержки удаленных устройств, поскольку вспомогательный персонал пользуется локальными системами, которые номинально идентичны системам на местах. Возможно, самым важным (но и самым коварным) преимуществом является то, что ro-rootfs заставляет разработчиков решать, какие системные объекты будут неизменными, еще на этапе проектирования системы. Работа с ro-rootfs может быть неудобной и болезненной, как это часто бывает с переменными const в языках программирования, но их преимущества легко окупают дополнительные накладные расходы.
Создание rootfs только для чтения требует некоторых дополнительных усилий для разработчиков встраиваемых систем, и именно здесь на сцену выходит VFS. Linux требует, чтобы файлы в /var были доступны для записи, и, кроме того, многие популярные приложения, которые запускают встроенные системы, будут пытаться создать конфигурационные dot-files в $HOME . Одним из решений для конфигурационных файлов в домашнем каталоге обычно является их предварительная генерация и сборка в rootfs . Для /var один из возможных подходов — это смонтировать его в отдельный раздел, доступный для записи, в то время как сам / монтируется только для чтения. Другой популярной альтернативой является использование связываемых или накладываемых маунтов (bind or overlay mounts).
Связываемые и накладываемые маунты, использование их контейнерами
Выполнение команды man mount – лучший способ узнать про связываемые и накладываемые маунты, которые дают разработчикам и системным администраторам возможность создавать файловую систему по одному пути, а затем предоставлять ее приложениям в другом. Для встроенных систем это означает возможность хранить файлы в /var на флеш-накопителе, доступном только для чтения, но накладываемое или связываемое монтирование пути из tmpfs в /var при загрузке позволит приложениям записывать туда заметки (scrawl). При следующем включении изменения в /var будут утеряны. Накладываемое монтирование создает объединение между tmpfs и нижележащей файловой системой и позволяет делать якобы изменения существующих файлов в ro-tootf тогда как связываемое монтирование может сделать новые пустые tmpfs папки видимыми как доступные для записи в ro-rootfs путях. В то время как overlayfs это правильный ( proper ) тип файловой системы, связываемое монтирование реализовано в пространстве имен VFS.
Основываясь на описании накладываемого и связываемого монтирования, никто не удивляется что Linux контейнеры активно их используют. Давайте понаблюдаем, что происходит, когда мы используем systemd-nspawn для запуска контейнера, используя инструмент mountsnoop от bcc .
Вызов system-nspawn запускает контейнер во время работы mountsnoop.py .
Посмотрим, что получилось:
Запуск mountsnoop во время «загрузки» контейнера показывает, что среда выполнения контейнера сильно зависит от связываемого монтирования (Отображается только начало длинного вывода).
Здесь systemd-nspawn предоставляет выбранные файлы в procfs и sysfs хоста в контейнер как пути в его rootfs . Кроме MS_BIND флага, который устанавливает связывающее монтирование, некоторые другие флаги в монтируемой системе определяют взаимосвязь между изменениями в пространстве имен хоста и контейнера. Например, связываемое монтирование может либо пропускать изменения в /proc и /sys в контейнер, либо скрывать их в зависимости от вызова.
Понимание внутреннего устройства Linux может казаться невыполнимой задачей, так как само ядро содержит гигантское количество кода, оставляя в стороне приложения пользовательского пространства Linux и интерфейсы системных вызовов в библиотеках на языке C, таких как glibc . Один из способов добиться прогресса — прочитать исходный код одной подсистемы ядра с акцентом на понимание системных вызовов и заголовков, обращенных к пространству пользователя, а также основных внутренних интерфейсов ядра, к примеру, таблица file_operations . Файловые операции обеспечивают принцип «все является файлом», поэтому управление ими особенно приятно. Исходные файлы ядра на языке C в каталоге верхнего уровня fs/ представляют реализацию виртуальных файловых систем, которые являются слоем оболочки, обеспечивающим широкую и относительно простую совместимость популярных файловых систем и устройств хранения. Монтирование со связыванием и накладыванием через пространства имен Linux — это волшебство VFS, которое делает возможным создание контейнеров и корневых файловых систем только для чтения. В сочетании с изучением исходного кода, средство ядра eBPF и его интерфейс bcc
делают исследование ядра проще, чем когда-либо.Друзья, напишите была ли эта статья полезной для вас? Возможно у вас есть какие-то комментарии или замечания? А тех, кому интересен курс «Администратор Linux», приглашаем на день открытых дверей, который пройдёт 18 апреля.
Источник