Механизм VFS relay

Механизм VFS relay позволяет реализовать гранулярное разделение информационных потоков между несколькими системными программами VFS в зависимости от пользовательских сценариев. Механизм VFS relay основан на VFS-бэкендах.

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

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

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

Описание публичных методов бэкенда VFS relay приведено в заголовочном файле sysroot-*-kos/include/vfs/relay.h.

Также см. пример vfs_relay, который расположен в директории examples/vfs_relay из состава SDK.

VFS relay в серверном приложении

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

В этом режиме для файлов и сокетов, открытых в серверной программе VFS (например open() в коде сервера или используемых им библиотек), будет сформирован локальный контекст открытия и локальный дескриптор (Handle), который может быть использован только в контексте этой серверной программы и не может быть передан по IPC клиентским программам VFS.

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

Подробнее см. "Управление дескрипторами".

Использование VFS relay бэкенда в серверном приложении

Для сборки программы, выполняющей роль VFS сервера, с использованием VFS relay бэкенда, необходимо указать зависимость от библиотек vfs::server и vfs:relay.

Пример указания библиотек для программы, выполняющей роль VFS сервера и использующей VFS relay бэкенд с client и local бэкендами:

find_package (vfs REQUIRED)

target_link_libraries (${PROJECT_NAME} vfs::server vfs::relay vfs::client vfs::local)

Настройка запуска программы, выполняющей функцию VFS сервера, в init.yaml проводится с помощью указания переменных окружения VFS_FILESYSTEM_BACKEND и/или VFS_NETWORK_BACKEND.

Программа VFS "по умолчанию" указывается после имени relay бэкенда через двоеточие.

Перед указанием VFS relay бэкенда, необходимо указать, что верхнеуровневым бэкендом является server, а так же указать идентификатор серверного бэкенда, например так: "server:RelayVfs:relay:client:kl.VfsEntity".

Для указания нижележащих программ VFS, которые будут автоматически подключены к VFS relay при старте необходимо воспользоваться переменной окружения VFS_RELAY_DESCENDANTS. Формат записи для дочернего клиента: "Метка_бэкенда=конфигурация_бэкенда". По используемой метке бэкенда возможно получение указателя на структуру VFS при переопределении методов VFS relay (см. ниже). В VFS_RELAY_DESCENDANTS можно перечислить сразу несколько дочерних бэкендов разделенных символом ";".

Пример init.yaml конфигурации для программы RelayVfsServer. Используется VFS relay бэкенд к которому подключена дочерняя программа kl.VfsEntity в качестве бэкенда "по умолчанию". Дополнительно подключены local бэкенд и client бэкенд с метками LocalVfs и UserVfsServer. Сетевые и файловые операции обрабатываются через общий VFS relay бэкенд.

- name: example.RelayVfsServer

path: RelayVfsServer

env:

VFS_FILESYSTEM_BACKEND: "server:RelayVfs:relay:client:kl.VfsEntity"

VFS_NETWORK_BACKEND: "server:RelayVfs:relay:client:kl.VfsEntity"

VFS_RELAY_DESCENDANTS: "LocalVfs=local;UserVfsServer=client:task:example.UserVfsServer"

@INIT_RelayVfsServer_ENTITY_CONNECTIONS@

VFS relay в клиентском приложении

Библиотека vfs::relay может быть скомпонована с пользовательской программой. Использование VFS relay в качестве бэкенда для клиентской программы позволяет ей одновременно использовать локальный бэкенд для выполнения операций над некоторыми файлами или сокетами и клиентский бэкенд для выполнения операций на отдельных программах VFS. В этом режиме для каждого открытого файла/сокета VFS relay бэкенд хранит локальный контекст открытия файла, который содержит информацию об используемом нижележащем бэкенде. Указателем на контекст открытия является локальный дескриптор (Handle), который может быть использован только в контексте данной программы и не может быть передан другим программам по IPC.

Использование VFS relay бэкенда в клиентском приложении

Для сборки клиентской программы с поддержкой VFS relay бэкенда необходимо указать в CMake-файле для сборки этой программы зависимость от библиотеки vfs:relay.

Пример указания библиотек при использовании VFS relay бэкенда c нижележащими local и client бэкендами, а так же необходимых для local бэкенда библиотек:

find_package (vfs REQUIRED)

target_link_libraries (${PROJECT_NAME} vfs::relay vfs::client vfs::local vfs::lib_fs)

В описании запуска клиентской программы в файл init.yaml нужно указать использование VFS relay бэкенда и бэкенда, который будет использоваться в качестве VFS "по умолчанию" с помощью переменных окружения VFS_FILESYSTEM_BACKEND и/или VFS_NETWORK_BACKEND.

Программа VFS "по умолчанию" указывается после имени VFS relay бэкенда через двоеточие.

Для указания нижележащих программ VFS, которые будут автоматически подключены к VFS relay при старте необходимо воспользоваться переменной окружения VFS_RELAY_DESCENDANTS. Формат записи для дочернего клиента: "Метка_бэкенда=конфигурация_бэкенда". По используемой метке бэкенда возможно получение указателя на структуру VFS при переопределении методов VFS relay (см. ниже). В VFS_RELAY_DESCENDANTS можно перечислить сразу несколько дочерних бэкендов разделенных символом ";".

Пример init.yaml конфигурации для программы SimpleMultiVfs. Используется VFS relay бэкенд к которому подключена дочерняя программа kl.VfsEntity в качестве бэкенда "по умолчанию", дополнительно подключен local бэкенд. Сетевые и файловые операции обрабатываются через общий VFS relay бэкенд.

- name: example.SimpleMultiVfs

path: SimpleMultiVfs

env:

VFS_FILESYSTEM_BACKEND: "relay:client:kl.VfsEntity"

VFS_NETWORK_BACKEND: "relay:client:kl.VfsEntity

VFS_RELAY_DESCENDANTS: "LocalVfs=local"

@INIT_SimpleMultiVfs_ENTITY_CONNECTIONS@

Выполнение файловых и сетевых операций

При выполнении пользовательских запросов основной задачей бэкенда VFS relay является выбор правильного нижележащего бэкенда для перенаправления операции. Логика выбора нижележащего бэкенда реализуется пользователем бэкенда в виде исполняемого кода, регистрируемого как callback-функция. Для каждого типа ресурсов (файл, сокет, пайп), можно установить независимую callback-функцию, в которой будет реализована логика по выбору нижележащего бэкенда. Выполнение операций над уже созданным ресурсом (файлом, сокетом, пайпом) будет автоматически перенаправлено в VFS бэкенд, который был использован при создании файла.

Функции для регистрации callback-функций определены в заголовочном файле sysroot-*-kos/include/vfs/relay.h.

Создание файла и файловые операции

Callback-функция на создание файла регистрируется с помощью функции relay_set_file_cb().

Callback-функция принимает в качестве параметров контекст подключения клиента и путь к файлу, для которого выполняется операция. Путь передается в абсолютном формате, размер массива path равен MAX_PATH .

Создание сокета

Callback-функция на создание сокета регистрируется с помощью функции relay_set_socket_cb().

Callback-функция принимает в качестве параметров контекст подключения клиента и набор атрибутов создаваемого сокета (domain, type, protocol).

Создание каналов

Callback-функция на создание неименованного канала (пайп) регистрируется с помощью функции relay_set_pipe_cb().

Вспомогательные функции

Получение указателя на нижележащие бэкенды, подключенные к VFS relay может быть выполнено с помощью функций relay_get_descendant(), relay_get_fs_vfs(), relay_get_net_vfs и relay_get_default_vfs().

Набор шаблонных callback-функций

Совместно с бэкендом VFS relay поставляется библиотека с набором методов, которые можно регистрировать в качестве callback-функций при выполнении операций в заголовочном файле sysroot-*-kos/include/vfs/relay_cb.h.

В начало