@@ -36,9 +36,11 @@ let create_rrd_vdi ~__context ~sr =
3636 ~_type:`rrd ~sharable: false ~read_only: false ~other_config: [] ~xenstore_data: [] ~sm_config: [] ~tags: [] )
3737 in
3838 debug " New SR-stats VDI created vdi=%s on sr=%s" (Ref. string_of vdi) (Ref. string_of sr);
39+ vdi
3940 end
4041 | vdi :: _ ->
41- debug " Found existing SR-stats VDI vdi=%s on sr=%s" (Ref. string_of vdi) (Ref. string_of sr)
42+ debug " Found existing SR-stats VDI vdi=%s on sr=%s" (Ref. string_of vdi) (Ref. string_of sr);
43+ vdi
4244
4345(* CA-26514: Block operations on 'unmanaged' VDIs *)
4446let assert_managed ~__context ~vdi =
@@ -178,3 +180,88 @@ let database_ref_of_vdi ~__context ~vdi =
178180 (fun () -> Helpers. call_api_functions ~__context
179181 (fun rpc session_id -> Sm_fs_ops. with_block_attached_device __context rpc session_id vdi `RW database_ref_of_device))
180182
183+ module VDI_CStruct = struct
184+
185+ let magic_number = 0x7ada7adal
186+ let magic_number_offset = 0
187+ let version = 1l
188+ let version_offset = 4
189+ let length_offset = 8
190+ let data_offset = 12
191+ let vdi_format_length = 12 (* VDI format takes 12bytes *)
192+ let vdi_size = 4194304 (* 4MiB *)
193+ let default_offset = 0
194+
195+ (* Set the magic number *)
196+ let set_magic_number cstruct =
197+ Cstruct.BE. set_uint32 cstruct magic_number_offset magic_number
198+
199+ (* Get the magic number *)
200+ let get_magic_number cstruct =
201+ Cstruct.BE. get_uint32 cstruct magic_number_offset
202+
203+ (* Set the version *)
204+ let set_version cstruct =
205+ Cstruct.BE. set_uint32 cstruct version_offset version
206+
207+ (* Set the data length *)
208+ let set_data_length cstruct len =
209+ Cstruct.BE. set_uint32 cstruct length_offset len
210+
211+ (* Get the data length *)
212+ let get_data_length cstruct =
213+ Cstruct.BE. get_uint32 cstruct length_offset
214+
215+ (* Write the string to the vdi *)
216+ let write_to_vdi cstruct text text_len =
217+ Cstruct. blit_from_string text default_offset cstruct data_offset text_len;
218+ set_data_length cstruct (Int32. of_int text_len)
219+
220+ (* Read the string from the vdi *)
221+ let read_from_vdi cstruct =
222+ let curr_len = Int32. to_int (get_data_length cstruct) in
223+ let curr_text = String. make curr_len '\000' in
224+ Cstruct. blit_to_string cstruct data_offset curr_text default_offset curr_len;
225+ curr_text
226+
227+ (* Format the vdi for the first time *)
228+ let format_rrd_vdi cstruct =
229+ set_magic_number cstruct;
230+ set_version cstruct
231+
232+ end
233+
234+ (* Write the rrd stats to the rrd-stats vdi *)
235+ let write_rrd ~__context ~sr ~vdi ~text =
236+ Helpers. call_api_functions ~__context
237+ (fun rpc session_id -> Sm_fs_ops. with_open_block_attached_device __context rpc session_id vdi `RW
238+ (fun fd ->
239+ let mapping = Bigarray. (Array1. map_file fd char c_layout true VDI_CStruct. vdi_size) in
240+ let cstruct = Cstruct. of_bigarray mapping in
241+ if (VDI_CStruct. get_magic_number cstruct) <> VDI_CStruct. magic_number then
242+ VDI_CStruct. format_rrd_vdi cstruct;
243+ let new_text_len = String. length text in
244+ if new_text_len > = (VDI_CStruct. vdi_size - VDI_CStruct. vdi_format_length) then
245+ error " Failure on rrd-stats vdi write, text length is more than 4MiB"
246+ else
247+ VDI_CStruct. write_to_vdi cstruct text new_text_len
248+ )
249+ )
250+
251+ (* Read the rrd stats from the rrd-stats vdi *)
252+ let read_rrd ~__context ~sr ~vdi =
253+ Helpers. call_api_functions ~__context
254+ (fun rpc session_id -> Sm_fs_ops. with_open_block_attached_device __context rpc session_id vdi `RW
255+ (fun fd ->
256+ let mapping = Bigarray. (Array1. map_file fd char c_layout false VDI_CStruct. vdi_size) in
257+ let cstruct = Cstruct. of_bigarray mapping in
258+ if (VDI_CStruct. get_magic_number cstruct) <> VDI_CStruct. magic_number then begin
259+ error " Failure on rrd-stats vdi read, vdi is not formatted" ;
260+ (* Nothing to return, VDI is not formatted *)
261+ None
262+ end
263+ else
264+ Some (VDI_CStruct. read_from_vdi cstruct)
265+ )
266+ )
267+
0 commit comments