1libfiemap 2============= 3 4`libfiemap` is a library for creating block-devices that are backed by 5storage in read-write partitions. It exists primary for gsid. Generally, the 6library works by using `libfiemap_writer` to allocate large files within 7filesystem, and then tracks their extents. 8 9There are three main uses for `libfiemap`: 10 - Creating images that will act as block devices. For example, gsid needs to 11 create a `system_gsi` image to store Dynamic System Updates. 12 - Mapping the image as a block device while /data is mounted. This is fairly 13 tricky and is described in more detail below. 14 - Mapping the image as a block device during first-stage init. This is simple 15 because it uses the same logic from dynamic partitions. 16 17Image creation is done through `SplitFiemap`. Depending on the file system, 18a large image may have to be split into multiple files. On Ext4 the limit is 1916GiB and on FAT32 it's 4GiB. Images are saved into `/data/gsi/<name>/` 20where `<name>` is chosen by the process requesting the image. 21 22At the same time, a file called `/metadata/gsi/<name>/lp_metadata` is created. 23This is a super partition header that allows first-stage init to create dynamic 24partitions from the image files. It also tracks the canonical size of the image, 25since the file size may be larger due to alignment. 26 27Mapping 28------- 29 30It is easy to make block devices out of blocks on `/data` when it is not 31mounted, so first-stage init has no issues mapping dynamic partitions from 32images. After `/data` is mounted however, there are two problems: 33 - `/data` is encrypted. 34 - `/dev/block/by-name/data` may be marked as in-use. 35 36We break the problem down into three scenarios. 37 38### FDE and Metadata Encrypted Devices 39 40When FDE or metadata encryption is used, `/data` is not mounted from 41`/dev/block/by-name/data`. Instead, it is mounted from an intermediate 42`dm-crypt` or `dm-default-key` device. This means the underlying device is 43not marked in use, and we can create new dm-linear devices on top of it. 44 45On these devices, a block device for an image will consist of a single 46device-mapper device with a `dm-linear` table entry for each extent in the 47backing file. 48 49### Unencrypted and FBE-encrypted Devices 50 51When a device is unencrypted, or is encrypted with FBE but not metadata 52encryption, we instead use a loop device with `LOOP_SET_DIRECT_IO` enabled. 53Since `/data/gsi` has encryption disabled, this means the raw blocks will be 54unencrypted as well. 55 56### Split Images 57 58If an image was too large to store a single file on the underlying filesystem, 59on an FBE/unencrypted device we will have multiple loop devices. In this case, 60we create a device-mapper device as well. For each loop device it will have one 61`dm-linear` table entry spanning the length of the device. 62 63State Tracking 64-------------- 65 66It's important that we know whether or not an image is currently in-use by a 67block device. It could be catastrophic to write to a dm-linear device if the 68underlying blocks are no longer owned by the original file. Thus, when mapping 69an image, we create a property called `gsid.mapped_image.<name>` and set it to 70the path of the block device. 71 72Additionally, we create a `/metadata/gsi/<subdir>/<name>.status` file. Each 73line in this file denotes a dependency on either a device-mapper node or a loop 74device. When deleting a block device, this file is used to release all 75resources. 76