Skip to content

Commit 5ec5732

Browse files
authored
doc: xapi storage layer doc update (#6351)
The storage layer code in xapi has undergone some changes: storage_impl.ml is no longer in the repo and is replaced by `storage_smapiv1_wrapper.ml` and `storage_smapiv1.ml`. Update the relevant docs to reflect this change.
2 parents 657aa71 + 51b800b commit 5ec5732

File tree

1 file changed

+66
-73
lines changed

1 file changed

+66
-73
lines changed

doc/content/xapi/storage/_index.md

+66-73
Original file line numberDiff line numberDiff line change
@@ -3,39 +3,33 @@ title = "XAPI's Storage Layers"
33
linkTitle = "Storage"
44
+++
55

6+
67
{{% notice info %}}
78
The links in this page point to the source files of xapi
8-
[v1.127.0](https://github.com/xapi-project/xen-api/tree/v1.127.0), and xcp-idl
9-
[v1.62.0](https://github.com/xapi-project/xcp-idl/tree/v1.62.0), not to the
10-
latest source code.
11-
12-
In the beginning of 2023, significant changes have been made in the layering.
13-
In particular, the wrapper code from `storage_impl.ml` has been pushed down the
14-
stack, below the mux, such that it only covers the SMAPIv1 backend and not
15-
SMAPIv3. Also, all of the code (from xcp-idl etc) is now present in this repo
16-
(xen-api).
9+
[v25.11.0](https://github.com/xapi-project/xen-api/tree/v25.11.0).
1710
{{% /notice %}}
1811

12+
1913
Xapi directly communicates only with the SMAPIv2 layer. There are no
2014
plugins directly implementing the SMAPIv2 interface, but the plugins in
2115
other layers are accessed through it:
2216

23-
{{<mermaid>}}
17+
```mermaid
2418
graph TD
2519
A[xapi] --> B[SMAPIv2 interface]
26-
B --> C[SMAPIv2 <-> SMAPIv1 translation: storage_access.ml]
20+
B --> C[SMAPIv2 <-> SMAPIv1 state machine: storage_smapiv1_wrapper.ml]
21+
C --> G[SMAPIv2 <-> SMAPIv1 translation: storage_smapiv1.ml]
2722
B --> D[SMAPIv2 <-> SMAPIv3 translation: xapi-storage-script]
28-
C --> E[SMAPIv1 plugins]
23+
G --> E[SMAPIv1 plugins]
2924
D --> F[SMAPIv3 plugins]
30-
{{< /mermaid >}}
25+
```
3126

3227
## SMAPIv1
3328

3429
These are the files related to SMAPIv1 in `xen-api/ocaml/xapi/`:
3530

36-
- [sm.ml](https://github.com/xapi-project/xen-api/blob/v1.127.0/ocaml/xapi/sm.ml):
37-
OCaml "bindings" for the SMAPIv1 Python "drivers" (SM)
38-
- [sm_exec.ml](https://github.com/xapi-project/xen-api/blob/v1.127.0/ocaml/xapi/sm_exec.ml):
31+
- sm.ml: OCaml "bindings" for the SMAPIv1 Python "drivers" (SM)
32+
- sm_exec.ml:
3933
support for implementing the above "bindings". The
4034
parameters are converted to XML-RPC, passed to the relevant python
4135
script ("driver"), and then the standard output of the program is
@@ -46,37 +40,39 @@ These are the files related to SMAPIv1 in `xen-api/ocaml/xapi/`:
4640
parameters in the args record.
4741
- `smint.ml`: Contains types, exceptions, ... for the SMAPIv1 OCaml
4842
interface
43+
- `storage_smapiv1_wrapper.ml`: A state machine for SMAPIv1 operations. It computes
44+
the required actions to reach the desired state from the current state.
45+
- `storage_smapiv1.ml`: Contains the actual translation of SMAPIv2 calls to SMAPIv1
46+
calls, by calling the bindings provided in sm.ml.
4947

5048
## SMAPIv2
5149

5250
These are the files related to SMAPIv2, which need to be modified to
5351
implement new calls:
5452

55-
- [xcp-idl/storage/storage\_interface.ml](https://github.com/xapi-project/xcp-idl/blob/v1.62.0/storage/storage_interface.ml):
53+
- [xcp-idl/storage/storage\_interface.ml](https://github.com/xapi-project/xen-api/blob/v25.11.0/ocaml/xapi-idl/storage/storage_interface.ml):
5654
Contains the SMAPIv2 interface
57-
- [xcp-idl/storage/storage\_skeleton.ml](https://github.com/xapi-project/xcp-idl/blob/v1.62.0/storage/storage_skeleton.ml):
55+
- [xcp-idl/storage/storage\_skeleton.ml](https://github.com/xapi-project/xen-api/blob/v25.11.0/ocaml/xapi-idl/storage/storage_skeleton.ml):
5856
A stub SMAPIv2 storage server implementation that matches the
5957
SMAPIv2 storage server interface (this is verified by
60-
[storage\_skeleton\_test.ml](https://github.com/xapi-project/xcp-idl/blob/v1.62.0/storage/storage_skeleton_test.ml)),
58+
[storage\_skeleton\_test.ml](https://github.com/xapi-project/xen-api/blob/v25.11.0/ocaml/xapi-idl/storage/storage_skeleton_test.ml)),
6159
each of its function just raise a `Storage_interface.Unimplemented`
6260
error. This skeleton is used to automatically fill the unimplemented
6361
methods of the below storage servers to satisfy the interface.
64-
- [xen-api/ocaml/xapi/storage\_access.ml](https://github.com/xapi-project/xen-api/blob/v1.127.0/ocaml/xapi/storage_access.ml):
65-
[module SMAPIv1](https://github.com/xapi-project/xen-api/blob/v1.127.0/ocaml/xapi/storage_access.ml#L104):
66-
a SMAPIv2 server that does SMAPIv2 -&gt; SMAPIv1 translation.
62+
- [xen-api/ocaml/xapi/storage\_smapiv1.ml](https://github.com/xapi-project/xen-api/blob/v25.11.0/ocaml/xapi/storage_smapiv1.ml):
63+
a SMAPIv2 server that does SMAPIv2 -> SMAPIv1 translation.
6764
It passes the XML-RPC requests as the first command-line argument to the
6865
corresponding Python script, which returns an XML-RPC response on standard
6966
output.
70-
- [xen-api/ocaml/xapi/storage\_impl.ml](https://github.com/xapi-project/xen-api/blob/v1.127.0/ocaml/xapi/storage_impl.ml):
71-
The
72-
[Wrapper](https://github.com/xapi-project/xen-api/blob/v1.127.0/ocaml/xapi/storage_impl.ml#L302)
67+
- [xen-api/ocaml/xapi/storage_smapiv1_wrapper.ml](https://github.com/xapi-project/xen-api/blob/v25.11.0/ocaml/xapi/storage_smapiv1_wrapper.ml):
68+
The [Wrapper](https://github.com/xapi-project/xen-api/blob/v25.11.0/ocaml/xapi/storage_smapiv1_wrapper.ml#L360)
7369
module wraps a SMAPIv2 server (Server\_impl) and takes care of
7470
locking and datapaths (in case of multiple connections (=datapaths)
7571
from VMs to the same VDI, it will use the superstate computed by the
76-
[Vdi_automaton](https://github.com/xapi-project/xcp-idl/blob/v1.62.0/storage/vdi_automaton.ml)
72+
[Vdi_automaton](https://github.com/xapi-project/xen-api/blob/v25.11.0/ocaml/xapi-idl/storage/vdi_automaton.ml)
7773
in xcp-idl). It also implements some functionality, like the `DP`
7874
module, that is not implemented in lower layers.
79-
- [xen-api/ocaml/xapi/storage\_mux.ml](https://github.com/xapi-project/xen-api/blob/v1.127.0/ocaml/xapi/storage_mux.ml):
75+
- [xen-api/ocaml/xapi/storage\_mux.ml](https://github.com/xapi-project/xen-api/blob/v25.11.0/ocaml/xapi/storage_mux.ml):
8076
A SMAPIv2 server, which multiplexes between other servers. A
8177
different SMAPIv2 server can be registered for each SR. Then it
8278
forwards the calls for each SR to the "storage plugin" registered
@@ -85,30 +81,30 @@ implement new calls:
8581
### How SMAPIv2 works:
8682

8783
We use [message-switch] under the hood for RPC communication between
88-
[xcp-idl](https://github.com/xapi-project/xcp-idl) components. The
84+
[xapi-idl](https://github.com/xapi-project/xen-api/tree/v25.11.0/ocaml/xapi-idl) components. The
8985
main `Storage_mux.Server` (basically `Storage_impl.Wrapper(Mux)`) is
9086
[registered to
91-
listen](https://github.com/xapi-project/xen-api/blob/v1.127.0/ocaml/xapi/storage_access.ml#L1279)
87+
listen](https://github.com/xapi-project/xen-api/blob/v25.11.0/ocaml/xapi/storage_access.ml#L500)
9288
on the "`org.xen.xapi.storage`" queue [during xapi's
93-
startup](https://github.com/xapi-project/xen-api/blob/v1.127.0/ocaml/xapi/xapi.ml#L801),
89+
startup](https://github.com/xapi-project/xen-api/blob/v25.11.0/ocaml/xapi/xapi.ml#L1080),
9490
and this is the main entry point for incoming SMAPIv2 function calls.
9591
`Storage_mux` does not really multiplex between different plugins right
9692
now: [earlier during xapi's
97-
startup](https://github.com/xapi-project/xen-api/blob/v1.127.0/ocaml/xapi/xapi.ml#L799),
93+
startup](https://github.com/xapi-project/xen-api/blob/v25.11.0/ocaml/xapi/xapi.ml#L1076),
9894
the same SMAPIv1 storage server module [is
99-
registered](https://github.com/xapi-project/xen-api/blob/v1.127.0/ocaml/xapi/storage_access.ml#L934)
95+
registered](https://github.com/xapi-project/xen-api/blob/v25.11.0/ocaml/xapi/storage_access.ml#L934)
10096
on the various "`org.xen.xapi.storage.<sr type>`" queues for each
10197
supported SR type. (This will change with SMAPIv3, which is accessed via
10298
a SMAPIv2 plugin outside of xapi that translates between SMAPIv2 and
10399
SMAPIv3.) Then, in
104-
[Storage\_access.create\_sr](https://github.com/xapi-project/xen-api/blob/v1.127.0/ocaml/xapi/storage_access.ml#L1531),
100+
[Storage\_access.create\_sr](https://github.com/xapi-project/xen-api/blob/v25.11.0/ocaml/xapi/storage_access.ml#L802),
105101
which is called
106-
[during SR.create](https://github.com/xapi-project/xen-api/blob/v1.127.0/ocaml/xapi/xapi_sr.ml#L326),
102+
[during SR.create](https://github.com/xapi-project/xen-api/blob/v25.11.0/ocaml/xapi/xapi_sr.ml#L391),
107103
and also
108-
[during PBD.plug](https://github.com/xapi-project/xen-api/blob/v1.127.0/ocaml/xapi/xapi_pbd.ml#L121),
104+
[during PBD.plug](https://github.com/xapi-project/xen-api/blob/v25.11.0/ocaml/xapi/xapi_pbd.ml#L175),
109105
the relevant "`org.xen.xapi.storage.<sr type>`" queue needed for that
110106
PBD is [registered with Storage_mux in
111-
Storage\_access.bind](https://github.com/xapi-project/xen-api/blob/v1.127.0/ocaml/xapi/storage_access.ml#L1107)
107+
Storage\_access.bind](https://github.com/xapi-project/xen-api/blob/v25.11.0/ocaml/xapi/storage_access.ml#L267)
112108
for the SR of that PBD.\
113109
So basically what happens is that xapi registers itself as a SMAPIv2
114110
server, and forwards incoming function calls to itself through
@@ -118,10 +114,10 @@ translation.
118114

119115
#### Registration of the various storage servers
120116

121-
{{<mermaid>}}
117+
```mermaid
122118
sequenceDiagram
123119
participant q as message-switch
124-
participant v1 as Storage_access.SMAPIv1
120+
participant v1 as Storage_smapiv1.SMAPIv1
125121
participant svr as Storage_mux.Server
126122
127123
Note over q, svr: xapi startup, "Starting SMAPIv1 proxies"
@@ -134,11 +130,11 @@ q ->> svr:org.xen.xapi.storage
134130
135131
Note over q, svr: SR.create, PBD.plug
136132
svr ->> q:org.xapi.storage.sr_type_2
137-
{{< /mermaid >}}
133+
```
138134

139135
#### What happens when a SMAPIv2 "function" is called
140136

141-
{{<mermaid>}}
137+
```mermaid
142138
graph TD
143139
144140
call[SMAPIv2 call] --VDI.attach2--> org.xen.xapi.storage
@@ -148,24 +144,24 @@ org.xen.xapi.storage
148144
org.xen.xapi.storage.SR_type_x
149145
end
150146
151-
org.xen.xapi.storage --VDI.attach2--> Storage_impl.Wrapper
147+
org.xen.xapi.storage --VDI.attach2--> Storage_smapiv1_wrapper.Wrapper
152148
153149
subgraph xapi
154150
subgraph Storage_mux.server
155-
Storage_impl.Wrapper --> Storage_mux.mux
151+
Storage_smapiv1_wrapper.Wrapper --> Storage_mux.mux
156152
end
157-
Storage_access.SMAPIv1
153+
Storage_smapiv1.SMAPIv1
158154
end
159155
160156
Storage_mux.mux --VDI.attach2--> org.xen.xapi.storage.SR_type_x
161-
org.xen.xapi.storage.SR_type_x --VDI.attach2--> Storage_access.SMAPIv1
157+
org.xen.xapi.storage.SR_type_x --VDI.attach2--> Storage_smapiv1.SMAPIv1
162158
163159
subgraph SMAPIv1
164160
driver_x[SMAPIv1 driver for SR_type_x]
165161
end
166162
167-
Storage_access.SMAPIv1 --vdi_attach--> driver_x
168-
{{< /mermaid >}}
163+
Storage_smapiv1.SMAPIv1 --vdi_attach--> driver_x
164+
```
169165

170166
### Interface Changes, Backward Compatibility, & SXM
171167

@@ -182,47 +178,44 @@ translation. However, the former has large portions of code in its intermediate
182178
layers, in addition to the basic SMAPIv2 <-> SMAPIv1 translation in
183179
`storage_access.ml`.
184180

185-
These are the three files in xapi that implement the SMAPIv2 storage interface,
181+
These are the two files in xapi that implement the SMAPIv2 storage interface,
186182
from higher to lower level:
187183

188-
- [xen-api/ocaml/xapi/storage\_impl.ml](https://github.com/xapi-project/xen-api/blob/v1.127.0/ocaml/xapi/storage_impl.ml):
189-
- [xen-api/ocaml/xapi/storage\_mux.ml](https://github.com/xapi-project/xen-api/blob/v1.127.0/ocaml/xapi/storage_mux.ml):
190-
- [xen-api/ocaml/xapi/storage\_access.ml](https://github.com/xapi-project/xen-api/blob/v1.127.0/ocaml/xapi/storage_access.ml):
184+
- [xen-api/ocaml/xapi/storage\_mux.ml](https://github.com/xapi-project/xen-api/blob/v25.11.0/ocaml/xapi/storage_mux.ml):
185+
- [xen-api/ocaml/xapi/storage\_access.ml](https://github.com/xapi-project/xen-api/blob/v25.11.0/ocaml/xapi/storage_access.ml):
191186

192187
Functionality implemented by higher layers is not implemented by the layers below it.
193188

194-
#### Extra functionality in `storage_impl.ml`
195-
196-
In addition to its usual functions, `Storage_impl.Wrapper` also implements the
197-
`UPDATES` and `TASK` SMAPIv2 APIs, without calling the wrapped module.
189+
#### Extra functionality in `storage_task.ml`
198190

199-
These are backed by the `Updates`, `Task_server`, and `Scheduler` modules from
191+
`storage_smapiv1_wrapper.ml` also implements the `UPDATES` and `TASK` SMAPIv2 APIs. These are backed by the `Updates`, `Task_server`, and `Scheduler` modules from
200192
xcp-idl, instantiated in xapi's `Storage_task` module. Migration code in
201193
`Storage_mux` will interact with these to update task progress. There is also
202194
an event loop in xapi that keeps calling `UPDATES.get` to keep the tasks in
203195
xapi's database in sync with the storage manager's tasks.
204196

205-
`Storage_impl.Wrapper` also implements the legacy `VDI.attach` call by simply
197+
`Storage_smapiv1_wrapper.ml` also implements the legacy `VDI.attach` call by simply
206198
calling the newer `VDI.attach2` call in the same module. In general, this is a
207199
good place to implement a compatibility layer for deprecated functionality
208200
removed from other layers, because this is the first module that intercepts a
209201
SMAPIv2 call.
210202

211203
#### Extra functionality in `storage_mux.ml`
212204

213-
`Storage_mux` implements storage motion (SXM): it implements the `DATA` and
214-
`DATA.MIRROR` modules. Migration code will use the `Storage_task` module to run
215-
the operations and update the task's progress.
205+
`Storage_mux` redirects all storage motion (SXM) code to `storage_migrate.ml`,
206+
and the multiplexed will be managed by `storage_migrate.ml`. The main implementation
207+
resides in the `DATA` and `DATA.MIRROR` modules. Migration code will use
208+
the `Storage_task` module to run the operations and update the task's progress.
216209

217210
It also implements the `Policy` module from the SMAPIv2 interface.
218211

219212
## SMAPIv3
220213

221214
[SMAPIv3](https://xapi-project.github.io/xapi-storage/) has a slightly
222215
different interface from SMAPIv2.The
223-
[xapi-storage-script](https://github.com/xapi-project/xapi-storage-script)
216+
[xapi-storage-script](https://github.com/xapi-project/xen-api/tree/v25.11.0/ocaml/xapi-storage-script)
224217
daemon is a SMAPIv2 plugin separate from xapi that is doing the SMAPIv2
225-
↔ SMAPIv3 translation. It keeps the plugins registered with xcp-idl
218+
↔ SMAPIv3 translation. It keeps the plugins registered with xapi-idl
226219
(their message-switch queues) up to date as their files appear or
227220
disappear from the relevant directory.
228221

@@ -266,7 +259,7 @@ stored in subdirectories of the
266259
`/usr/libexec/xapi-storage-script/datapath/` directories, respectively.
267260
When it finds a new datapath plugin, it adds the plugin to a lookup table and
268261
uses it the next time that datapath is required. When it finds a new volume
269-
plugin, it binds a new [message-switch] queue named after the plugin's
262+
plugin, it binds a new [message-switch](https://github.com/xapi-project/xen-api/blob/v25.11.0/ocaml/xapi-storage-script/main.ml#L2023) queue named after the plugin's
270263
subdirectory to a new server instance that uses these volume scripts.
271264

272265
To invoke a SMAPIv3 method, it executes a program named
@@ -278,11 +271,11 @@ are type-checked using the generated Python bindings, and so are the
278271
outputs. The URIs of the SRs that xapi-storage-script knows about are
279272
stored in the `/var/run/nonpersistent/xapi-storage-script/state.db`
280273
file, these URIs can be used on the command line when an sr argument is
281-
expected.` `
274+
expected.
282275

283276
#### Registration of the various SMAPIv3 plugins
284277

285-
{{<mermaid>}}
278+
```mermaid
286279
sequenceDiagram
287280
participant q as message-switch
288281
participant v1 as (Storage_access.SMAPIv1)
@@ -306,11 +299,11 @@ q ->> svr:org.xen.xapi.storage
306299
307300
Note over q, svr: SR.create, PBD.plug
308301
svr ->> q:org.xapi.storage.sr_type_4
309-
{{< /mermaid >}}
302+
```
310303

311304
#### What happens when a SMAPIv3 "function" is called
312305

313-
{{<mermaid>}}
306+
```mermaid
314307
graph TD
315308
316309
call[SMAPIv2 call] --VDI.attach2--> org.xen.xapi.storage
@@ -348,28 +341,28 @@ end
348341
end
349342
350343
org.xen.xapi.storage.SR_type_x --VDI.attach2-->xapi-storage-script
351-
{{< /mermaid >}}
344+
```
352345

353346
## Error reporting
354347

355348
In our SMAPIv1 OCaml "bindings" in xapi
356-
([xen-api/ocaml/xapi/sm\_exec.ml](https://github.com/xapi-project/xen-api/blob/v1.127.0/ocaml/xapi/sm_exec.ml)),
349+
([xen-api/ocaml/xapi/sm\_exec.ml](https://github.com/xapi-project/xen-api/blob/v25.11.0/ocaml/xapi/sm_exec.ml)),
357350
[when we inspect the error codes returned from a call to
358-
SM](https://github.com/xapi-project/xen-api/blob/v1.127.0/ocaml/xapi/sm_exec.ml#L199),
351+
SM](https://github.com/xapi-project/xen-api/blob/v25.11.0/ocaml/xapi/sm_exec.ml#L421),
359352
we translate some of the SMAPIv1/SM error codes to XenAPI errors, and
360353
for others, we just [construct an error
361354
code](https://github.com/xapi-project/xen-api/blob/v1.127.0/ocaml/xapi/sm_exec.ml#L214)
362355
of the form `SR_BACKEND_FAILURE_<SM error number>`.
363356

364357
The file
365-
[xcp-idl/storage/storage\_interface.ml](https://github.com/xapi-project/xcp-idl/blob/v1.62.0/storage/storage_interface.ml#L362)
358+
[xcp-idl/storage/storage\_interface.ml](https://github.com/xapi-project/xen-api/blob/v25.11.0/ocaml/xapi-idl/storage/storage_interface.ml#L343)
366359
defines a number of SMAPIv2 errors, ultimately all errors from the various
367360
SMAPIv2 storage servers in xapi will be returned as one of these. Most of the
368361
errors aren't converted into a specific exception in `Storage_interface`, but
369362
are simply wrapped with `Storage_interface.Backend_error`.
370363

371364
The
372-
[Storage\_access.transform\_storage\_exn](https://github.com/xapi-project/xen-api/blob/v1.127.0/ocaml/xapi/storage_access.ml#L29)
365+
[Storage\_utils.transform\_storage\_exn](https://github.com/xapi-project/xen-api/blob/v25.11.0/ocaml/xapi/storage_utils.ml#L133)
373366
function is used by the client code in xapi to translate the SMAPIv2
374367
errors into XenAPI errors again, this unwraps the errors wrapped with
375368
`Storage_interface.Backend_error`.
@@ -379,7 +372,7 @@ errors into XenAPI errors again, this unwraps the errors wrapped with
379372
In the message forwarding layer, first we check the validity of VDI
380373
operations using `mark_vdi` and `mark_sr`. These first check that the
381374
operation is valid operations,
382-
using [Xapi\_vdi.check\_operation\_error](https://github.com/xapi-project/xen-api/blob/v1.127.0/ocaml/xapi/xapi_vdi.ml#L57),
375+
using [Xapi\_vdi.check\_operation\_error](https://github.com/xapi-project/xen-api/blob/v25.11.0/ocaml/xapi/xapi_vdi.ml#L65),
383376
for `mark_vdi`, which also inspects the current operations of the VDI,
384377
and then, if the operation is valid, it is added to the VDI's current
385378
operations, and update\_allowed\_operations is called. Then we forward
@@ -390,7 +383,7 @@ VDI's SR.
390383

391384
For the VDI operations, we check at two different places whether the SR
392385
is attached: first, at the Xapi level, [in
393-
Xapi\_vdi.check\_operation\_error](https://github.com/xapi-project/xen-api/blob/v1.127.0/ocaml/xapi/xapi_vdi.ml#L98),
386+
Xapi\_vdi.check\_operation\_error](https://github.com/xapi-project/xen-api/blob/v25.11.0/ocaml/xapi/xapi_vdi.ml#L133),
394387
for the resize operation, and then, at the SMAPIv1 level, in
395388
`Sm.assert_pbd_is_plugged`. `Sm.assert_pbd_is_plugged` performs the
396389
same checks, plus it checks that the PBD is attached to the localhost,

0 commit comments

Comments
 (0)