Notes:
- LVM operates in "segments" which are typically (but not always) 4MiB
- device mapper operates in sectors which are either 512 or 4096
- the system should operate in terms of segments (being bigger) and the local allocator can translate down to sectors when needed
- the types below haven't been optimised: in particular there's overlap between the structure of the dm types and the LVM types.
- suspend/ resume signalling is missing
- we should allow the ring to be poisoned, just in case someone reads a ring which has been deallocated
- we will uniquely identify LVs by their UUID, not their name. In particular when we rename an LV, the UUID will not change.
- we will uniquely identify PVs by their UUID, not their name.
- we should specify a byte ordering (little-endian?)
/* The unique id of the PV */
#define PV_ID_LENGTH 32
/* Contiguous physical extents on a single PV */
struct physical_extents {
char pv[PV_ID_LENGTH];
uint64_t offset; /* in extents */
uint64_t count; /* in extents */
}
#define LV_ID_LENGTH 32
/*************************************************************************/
/* Request to expand an LVM LV by a single segment, sent to the master */
struct expand_volume {
char volume[LV_ID_LENGTH];
physical_extents new_storage;
uint64_t virtual_extent; /* location in the LV, in extents */
}
/*************************************************************************/
/* The maximum length of a DM device appears to be 127 chars + trailing NULL
on Linux-3.13 */
#define DM_DEVICE_LENGTH 128
struct dm_linear_target {
uint32_t major;
uint32_t minor;
uint64_t virtual_sector;
uint64_t physical_sector;
uint64_t sector_count;
}
struct expand_dm_device {
physical_extents used; /* to remove from the free pool */
char dm_device[DM_DEVICE_LENGTH];
dm_linear_target dm_target;
}
/*************************************************************************/
/* The local allocator's transaction */
struct local_allocator_journal {
expand_volume volume;
expand_dm_device device;
}