VFS relay mechanism

The VFS relay mechanism lets you implement granular distribution of data streams among multiple VFS system programs depending on the user scenarios. The VFS relay mechanism is based on VFS backends.

In contrast to creating your own VFS backend in which the rules for selecting various VFS programs for performing file or network operations must be implemented on the client application side, the VFS relay mechanism lets you use a separate VFS server program that implements such rules and several of its associated underlying VFS programs to which the VFS server program forwards requests from client applications.

The rules for selecting the underlying VFS program when creating a file or socket are generated as executable code. The user needs to implement methods that can determine whether the file or socket belongs to a specific VFS program based on the parameters of the system call. Subsequent operations performed on the created files or sockets are automatically redirected to the VFS program that was assigned to the file or socket when it was created. For more details, refer to "Performing file and network operations" below.

The VFS component comes with the vfs::relay library, which lets you build a VFS server program that will redirect calls of functions for working with files and the network to VFS client programs. Alternatively, the vfs::relay library can be used locally, in which case the vfs::relay library is linked directly to the client application. For more details, refer to "VFS relay in a server application" and "VFS relay in a client application" below.

The public methods of the VFS relay backend are described in the header file sysroot-*-kos/include/vfs/relay.h.

Also see the vfs_relay example located in examples/vfs_relay from the SDK.

VFS relay in a server application

The vfs::relay library can be linked to a user program performing the VFS server role. This usage case allows the separation of data streams on the server side without the need to rebuild or change the configuration of client applications. In this case, the operation can be performed both in the VFS server program itself and it can be redirected to the underlying VFS client programs via IPC.

In this mode, a local opening context and a local handle (Handle) will be generated for files and sockets opened in the VFS server program (for example, open() in the server code or the libraries that it uses), and this handle can only be used in the context of this server program and cannot be transmitted over IPC to VFS client programs.

For files and sockets that were created when executing IPC requests from client applications, an OCAP badge is generated and this will create a unique OCAP handle that indicates the context of opening a file or socket. This handle can be passed to client applications and can be passed via IPC to the underlying VFS programs connected to the same VFS server.

For more details, refer to Managing handles.

Using the VFS relay backend in a server application

To build a program that performs the VFS server role using the VFS relay backend, you must specify the dependency on the vfs::server and vfs:relay libraries.

Example of specifying libraries for a program that performs the VFS server role and uses a VFS relay backend with client and local backends:

find_package (vfs REQUIRED)

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

The startup of a program that performs the VFS server function is configured in init.yaml by specifying the VFS_FILESYSTEM_BACKEND and/or VFS_NETWORK_BACKEND environment variables.

The default VFS program is specified after the name of the relay backend, separated by a colon.

Before specifying the VFS relay backend, you must specify that the top-level backend is the server, and also specify the server backend ID, such as server:RelayVfs:relay:client:kl.VfsEntity.

To specify the underlying VFS programs that will be automatically connected to the VFS relay at startup, you must use the VFS_RELAY_DESCENDANTS environment variable. The entry format for the child client is Backend_label=backend_configuration. Based on the backend label being used, you can obtain a pointer to the VFS structure when redefining the VFS relay methods (see below). In VFS_RELAY_DESCENDANTS, you can simultaneously list multiple child backends separated by the ; symbol.

Example init.yaml configuration for the RelayVfsServer program. It uses the VFS relay backend to which the kl.VfsEntity child program is connected as the default backend. The local backend and client backend with the labels LocalVfs and UserVfsServer are also connected. Network and file operations are handled through a shared VFS relay backend.

- 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 in a client application

The vfs::relay library can be linked to a user program. Use of the VFS relay as a backend for a client program allows the program to simultaneously use the local backend to perform operations on some files or sockets and use the client backend to perform operations on individual VFS programs. In this mode, for each opened file/socket of the VFS relay, the backend stores the local file opening context that contains information about the underlying backend being used. A pointer to the opening context is a local handle (handle), which can only be used in the context of this program and cannot be passed to other programs via IPC.

Using the VFS relay backend in a client application

To build a client program with support for the VFS relay backend, you must specify the dependency on the vfs:relay library in the CMake file for building this program.

Example of specifying libraries when using the VFS relay backend with the underlying local and client backends and the libraries required for the local backend:

find_package (vfs REQUIRED)

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

In the startup description for the client program in the init.yaml file, you must specify the use of the VFS relay backend and the backend that will be used as the default VFS via the VFS_FILESYSTEM_BACKEND and/or VFS_NETWORK_BACKEND environment variables.

The default VFS program is specified after the name of the VFS relay backend, separated by a colon.

To specify the underlying VFS programs that will be automatically connected to the VFS relay at startup, you must use the VFS_RELAY_DESCENDANTS environment variable. The entry format for the child client is Backend_label=backend_configuration. Based on the backend label being used, you can obtain a pointer to the VFS structure when redefining the VFS relay methods (see below). In VFS_RELAY_DESCENDANTS, you can simultaneously list multiple child backends separated by the ; symbol.

Example init.yaml configuration for the SimpleMultiVfs program. It uses the VFS relay backend to which the kl.VfsEntity child program is connected as the default backend, and the local backend is additionally connected. Network and file operations are handled through a shared VFS relay backend.

- 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@

Performing file and network operations

When completing user requests, the main task of the VFS relay backend is to select the correct underlying backend for redirecting the operation. The underlying backend selection logic is implemented by the backend user in the form of executable code that is registered as a callback function. For each type of resource (file, socket, pipe), you can set an independent callback function in which the logic for selecting the underlying backend will be implemented. Operations performed on an already created resource (file, socket, pipe) will be automatically redirected to the VFS backend that was used when creating the file.

The functions for registering callback functions are defined in the header file sysroot-*-kos/include/vfs/relay.h.

Creating a file and performing file operations

The callback function for file creation is registered using the relay_set_file_cb() function.

The parameters received by the callback function are the client connection context and the path to the file for which the operation is performed. The path is transmitted in absolute format, and the size of the path array is equal to MAX_PATH.

Socket creation

The callback function for socket creation is registered using the relay_set_socket_cb() function.

The parameters received by the callback function are the client connection context and the set of attributes of the created socket (domain, type, protocol).

Creating channels

The callback function for creating an unnamed channel (pipe) is registered using the relay_set_pipe_cb() function.

Auxiliary functions

The pointer to the underlying backends connected to the VFS relay can be received by using the relay_get_descendant(), relay_get_fs_vfs(), relay_get_net_vfs, and relay_get_default_vfs() functions.

Set of template callback functions

A library containing a set of methods that can be registered as callback functions when performing operations in the header file sysroot-*-kos/include/vfs/relay_cb.h is supplied together with the VFS relay backend.

Page top