SpaceOS wire protocol codecs for host-guest communication
at main 110 lines 2.6 kB view raw
1open Wire 2 3let magic = 0x53504F53 4 5type t = { 6 magic : int; 7 format_version : int; 8 reserved : int; 9 tenant_id : int; 10 total_blocks : int; 11 dp_start : int; 12 dp_size : int; 13 epoch : int64; 14 uuid : string; 15 crc32 : int; 16} 17 18let codec = 19 let open Codec in 20 record "Superblock" 21 (fun 22 magic 23 format_version 24 reserved 25 tenant_id 26 total_blocks 27 dp_start 28 dp_size 29 epoch 30 uuid 31 crc32 32 -> 33 { 34 magic; 35 format_version; 36 reserved; 37 tenant_id; 38 total_blocks; 39 dp_start; 40 dp_size; 41 epoch; 42 uuid; 43 crc32; 44 }) 45 |+ field "magic" uint32be (fun t -> t.magic) 46 |+ field "format_version" uint8 (fun t -> t.format_version) 47 |+ field "reserved" uint8 (fun t -> t.reserved) 48 |+ field "tenant_id" uint16be (fun t -> t.tenant_id) 49 |+ field "total_blocks" uint32be (fun t -> t.total_blocks) 50 |+ field "dp_start" uint32be (fun t -> t.dp_start) 51 |+ field "dp_size" uint32be (fun t -> t.dp_size) 52 |+ field "epoch" uint64be (fun t -> t.epoch) 53 |+ field "uuid" (byte_array ~size:(int 16)) (fun t -> t.uuid) 54 |+ field "crc32" uint32be (fun t -> t.crc32) 55 |> seal 56 57let crc32c data = 58 let v = 59 Checkseum.Crc32c.digest_string data 0 (String.length data) 60 Checkseum.Crc32c.default 61 in 62 Optint.to_unsigned_int v 63 64let compute_crc t = 65 (* CRC covers bytes 0-47 (everything before the CRC field) *) 66 let wire_size = Codec.wire_size codec in 67 let buf = Bytes.create wire_size in 68 Codec.encode codec t buf 0; 69 (* CRC covers first 48 bytes (wire_size - 4) *) 70 let crc_len = wire_size - 4 in 71 crc32c (Bytes.sub_string buf 0 crc_len) 72 73let v ~tenant_id ~total_blocks ~dp_start ~dp_size ~epoch ~uuid = 74 let t = 75 { 76 magic; 77 format_version = 0x01; 78 reserved = 0; 79 tenant_id; 80 total_blocks; 81 dp_start; 82 dp_size; 83 epoch; 84 uuid; 85 crc32 = 0; 86 } 87 in 88 { t with crc32 = compute_crc t } 89 90let check_magic t = t.magic = magic 91 92let check_crc t = 93 let expected = compute_crc { t with crc32 = 0 } in 94 t.crc32 = expected 95 96let pp ppf t = 97 Fmt.pf ppf 98 "@[<h>superblock(magic=0x%08x ver=%d tenant=%d blocks=%d dp=%d+%d \ 99 crc=0x%08x)@]" 100 t.magic t.format_version t.tenant_id t.total_blocks t.dp_start t.dp_size 101 t.crc32 102 103let equal a b = 104 a.magic = b.magic 105 && a.format_version = b.format_version 106 && a.tenant_id = b.tenant_id 107 && a.total_blocks = b.total_blocks 108 && a.dp_start = b.dp_start && a.dp_size = b.dp_size 109 && Int64.equal a.epoch b.epoch 110 && String.equal a.uuid b.uuid && a.crc32 = b.crc32