1.1 --- a/docs/wiki/Server_Library Mon Nov 21 01:19:48 2022 +0100
1.2 +++ b/docs/wiki/Server_Library Thu Dec 01 17:55:12 2022 +0100
1.3 @@ -3,8 +3,8 @@
1.4 Within the filesystem server library, a number of different abstractions and
1.5 mechanisms are employed to provide access to filesystem objects.
1.6
1.7 -The server library is provided by `libfsserver` within the `departure`
1.8 -package.
1.9 +The server library is provided by [[Libraries#libfsserver|`libfsserver`]]
1.10 +within the `departure` package.
1.11
1.12 <<TableOfContents(2,3)>>
1.13
1.14 @@ -12,9 +12,10 @@
1.15 within the described mechanisms will themselves be described using such
1.16 syntax.
1.17
1.18 -== Accountable ==
1.19 +((Accountable))
1.20 +== Accountables ==
1.21
1.22 -This interface provides the following operations:
1.23 +The `Accountable` interface provides the following operations:
1.24
1.25 {{{
1.26 void attach();
1.27 @@ -28,6 +29,9 @@
1.28 they may perform operations to tidy up after themselves and permit their
1.29 deallocation.
1.30
1.31 +The [[#Provider|`Provider`]] abstraction employs this interface to record its
1.32 +usage by multiple resources.
1.33 +
1.34 == Accessors ==
1.35
1.36 Accessors provide the means of accessing filesystem object data and metadata.
1.37 @@ -40,9 +44,22 @@
1.38 listings, obtaining the relevant filesystem metadata using the underlying
1.39 filesystem access library.
1.40
1.41 +The `DirectoryAccessor` interface provides the following operation:
1.42 +
1.43 +{{{
1.44 +void read_directory(file_t *writer);
1.45 +}}}
1.46 +
1.47 +The `read_directory` operation is presented with a writer object into which
1.48 +directory listing data will be written. In the case of the ext2 directory
1.49 +accessor, the writer is presented to a directory iterator which traverses the
1.50 +directory data structure, invoking a callback sending directory entries via
1.51 +the writer to the client.
1.52 +
1.53 === File Accessors ===
1.54
1.55 -File content is accessed through an interface with the following operations:
1.56 +File content is accessed through the `Accessor` interface with the following
1.57 +operations:
1.58
1.59 {{{
1.60 void close();
1.61 @@ -54,15 +71,17 @@
1.62
1.63 The operations need to be supported with actual filesystem operations. For
1.64 example, ext2-based filesystems employ a specific abstraction which invokes
1.65 -library functions provided by the `libext2fs` package.
1.66 +library functions provided by [[Libraries#libext2fs|`libext2fs`]].
1.67
1.68 +((Provider))
1.69 == Providers ==
1.70
1.71 Providers encapsulate the essential functionality for accessing filesystem
1.72 objects. Implementing the `Accountable` interface, they are shared by
1.73 resources and discarded when no resources are using them.
1.74
1.75 -The following operations are supported by providers:
1.76 +The following operations are supported by providers as defined by the
1.77 +`Provider` interface:
1.78
1.79 {{{
1.80 ProviderRegistry *registry();
1.81 @@ -71,23 +90,34 @@
1.82 void remove_pending(bool remove);
1.83 }}}
1.84
1.85 -Providers are associated with filesystem objects in a registry which can be
1.86 -obtained from each provider using the `registry` operation.
1.87 +=== Origin and Ownership ===
1.88 +
1.89 +A provider is created to represent a filesystem object when an attempt is made
1.90 +to open that object. It is then recorded in a provider registry so that
1.91 +subsequent attempts to open the object yield a common provider instance. The
1.92 +provider registry having ownership of each provider can be obtained using its
1.93 +`registry` operation.
1.94 +
1.95 +See the [[Filesystem Access#Opening Files|file opening mechanism]] for details
1.96 +of the creation and registration of providers.
1.97 +
1.98 +=== Resource Creation ===
1.99
1.100 Providers also support the creation of resources through which each user of a
1.101 provider exercises its use of that provider. The `make_resource` operation
1.102 performs the creation and returns size, flags and resource instance details.
1.103
1.104 -The removal of providers can be directed using the `remove_pending` operation.
1.105 -Where `remove_pending` has been called with a true value as its parameter, the
1.106 -`removal_pending` operation will also return a true value, and upon the
1.107 -provider being discarded, a removal operation will be invoked on the
1.108 -underlying object being provided.
1.109 +See the [[Filesystem Access#Opening Files|file opening mechanism]] for details
1.110 +of resource creation.
1.111 +
1.112 +=== Deallocation ===
1.113
1.114 -Typically, removal of providers is managed by the provider registry when
1.115 -resources are closed and detached from providers.
1.116 +Deallocation of providers is managed by the provider registry when resources
1.117 +are closed and detached from providers. Since the registry effectively has
1.118 +ownership of the provider, having registered it, the registry must therefore
1.119 +be involved in its deallocation, deregistering it first.
1.120
1.121 -######## A graph showing the removal mechanism
1.122 +######## A graph showing the deallocation mechanism
1.123
1.124 {{{#!graphviz
1.125 #format svg
1.126 @@ -99,28 +129,56 @@
1.127
1.128 ResourceServer -> Resource [label="close"];
1.129 Resource -> ProviderRegistry [label="detach"];
1.130 - ProviderRegistry -> Provider [label="delete"];
1.131 + ProviderRegistry -> Provider [label="detach\ndelete"];
1.132 }
1.133 }}}
1.134
1.135 ########
1.136
1.137 +=== Filesystem Object Removal ===
1.138 +
1.139 +The removal of filesystem objects that are being represented by providers can
1.140 +be directed using the `remove_pending` operation. Where `remove_pending` has
1.141 +been called with a true value as its parameter, the `removal_pending`
1.142 +operation will also return a true value, and upon the provider being
1.143 +discarded, a removal operation will be invoked on the underlying object being
1.144 +provided.
1.145 +
1.146 +See the [[Filesystem Access#Removing Files|file removal mechanism]] for more
1.147 +details of the invocations involved.
1.148 +
1.149 +((Resource))
1.150 == Resources ==
1.151
1.152 Resources are objects accessed by clients that support a basic level of
1.153 -accounting and management.
1.154 +accounting and management. They act as servers and receive messages via the
1.155 +interprocess communication (IPC) mechanism.
1.156
1.157 -The base interface of a resource is as follows:
1.158 +The `Resource` abstraction is intended to work with lower-level mechanisms
1.159 +provided by [[Libraries#libipc|`libipc`]] involving data structures and
1.160 +functions that are usable in the C programming language. This abstraction
1.161 +integrates the fundamental `libipc` support with C++.
1.162 +
1.163 +The generic operations of the `Resource` interface are as follows:
1.164
1.165 {{{
1.166 void activate();
1.167 void close();
1.168 }}}
1.169
1.170 -Activation of a resource is an optional operation that performs any
1.171 -initialisation before a resource is made available to its user.
1.172 +The activation of a resource, supported by `activate`, is an optional
1.173 +operation that performs any initialisation before a resource is made available
1.174 +as a server.
1.175 +
1.176 +The `close` operation is invoked when resources are to be discarded.
1.177
1.178 -In practice, other operations are required to make resources useful.
1.179 +See the [[Filesystem Access#Closing Files|file closing mechanism]] for the
1.180 +context in which the `close` operation is invoked.
1.181 +
1.182 +In practice, other operations are required to make resources useful. Such
1.183 +other operations are provided by classes inheriting from `Resource` and thus
1.184 +specialising it. Such classes also inherit from IPC interface types so as to
1.185 +be able to support the invocation of operations exposed by such interfaces.
1.186
1.187 In some cases, resources provide the mechanism by which each user of a
1.188 filesystem object may access that object independently. They would then
1.189 @@ -154,6 +212,46 @@
1.190 being the instantiation of an `OpenerResource` configured for the indicated
1.191 user identity.
1.192
1.193 +=== Server Framework Integration ===
1.194 +
1.195 +Resources must also support specific operations for integration with the
1.196 +lower-level IPC handling implemented in `libipc`. The following operations
1.197 +will be invoked by the server framework in `libfsserver` to configure a server
1.198 +controlled by `libipc`:
1.199 +
1.200 +{{{
1.201 +int expected_items();
1.202 +ipc_server_handler_type handler();
1.203 +void *interface();
1.204 +}}}
1.205 +
1.206 +The `expected_items` operation returns the number of message items expected
1.207 +from clients invoking server operations exposed via IPC. Typically, the
1.208 +returned value will be calculated for a given server interface by a tool such
1.209 +as `idl`, provided by the idl4re distribution.
1.210 +
1.211 +The `handler` operation returns a reference to a handler function able to
1.212 +interpret the operation codes in incoming messages and to dispatch to the
1.213 +appropriate operations provided by the resource. Typically, such a function
1.214 +will be generated by a tool such as `idl`.
1.215 +
1.216 +The `interface` operation returns a pointer to the resource instance, coerced
1.217 +to an appropriate type for the handler function. Such a type will be that of
1.218 +the most specialised IPC interface type inherited by the resource
1.219 +implementation. The function returned by the `handler` operation will expect a
1.220 +pointer to an instance of this appropriate type.
1.221 +
1.222 +For example, consider the following:
1.223 +
1.224 +{{{
1.225 +class FilePager : public Pager, public MappedFileObject
1.226 +}}}
1.227 +
1.228 +Here, the `interface` operation will return a pointer coerced to
1.229 +`MappedFileObject`, and the `handler` operation will return a reference to a
1.230 +function expecting to be able to interpret this pointer as referring to
1.231 +precisely that type.
1.232 +
1.233 == Registries ==
1.234
1.235 The basic mechanism for obtaining a resource involves a registry, as