Module Mkernel.BlockSource

Sourcetype t

The type of block devices.

Sourceval sector_size : t -> int

sector_size t returns the number of bytes in a sector, where "sector" is a fixed length block, the unit for memory allocation and block-device mapping performed by the functions above.

Sourceval length : t -> int

length t returns the length of the block device (in bytes).

Sourceval atomic_read : t -> src_off:int -> ?dst_off:int -> bigstring -> unit

atomic_read t ~src_off ?dst_off bstr reads data of sector_size t bytes into the buffer bstr (starting at byte dst_off) from the block device t at byte src_off. Always reads the full amount of sector_size t bytes ("short reads" are not possible).

This operation is called atomic, meaning that it is indivisible and irreducible. What's more, Miou can't do anything else (such as execute other tasks) until this operation has been completed.

The advantage of this type of operation is that you can assume a precise state, not only of the memory but also of the block-device, which cannot change during the read.

The disadvantage is that this operation can take a long time (and make your unikernel unavailable to all events for the duration of the operation) depending on the file system used by the host and the hardware used to store the block-device.

  • raises Invalid_argument

    if src_off is not a multiple of sector_size t or if the length of bstr is not equal to sector_size t.

Sourceval atomic_write : t -> ?src_off:int -> dst_off:int -> bigstring -> unit

atomic_write t ~src_off ?dst_off bstr writes data sector_size t bytes from the buffer bstr (at byte dst_off) to the block device identified by t, starting at byte src_off. Data is either written in it's entirety or not at all ("short writes" are not possible).

This operation is called atomic, meaning that it is indivisible and irreducible. What's more, Miou can't do anything else (such as execute other tasks) until this operation has been completed.

  • raises Invalid_argument

    if dst_off is not a multiple of sector_size t or if the length of bstr is not equal to sector_size t.

Scheduled operations on block-devices.

As far as operations on scheduled block-devices are concerned, here's a description of when Miou performs these operations.

As soon as Miou tries to observe possible events (such as the reception of a packet - see Net.read_bigstring), it also performs a (single) block-device operation. If Miou still has time (such as waiting for the end of a sleep), it can perform several operations on the block-devices until it runs out of time.

In short, operations on scheduled block-devices have the lowest priority. A unikernel can't go faster than the operations on waiting block-devices, so it's said to be I/O-bound on block-devices.

Sourceval read : t -> src_off:int -> ?dst_off:int -> bigstring -> unit

Like atomic_read, but the operation is scheduled. That is, it's not actually done, but will be as soon as Miou gets the chance.

Sourceval write : t -> ?src_off:int -> dst_off:int -> bigstring -> unit

Like atomic_write, but the operation is scheduled. That is, it's not actually done, but will be as soon as Miou gets the chance.

Sourceval connect : string -> (t, [> `Msg of string ]) result

connect name returns a block device according to the given name. It must correspond to the name given as an argument to the Solo5 tender. For example, if the invocation of our unikernel with Solo5 corresponds to:

  $ solo5-hvt --block:disk=file.txt -- unikernel.hvt

The name of the block would be: "disk".