Skip to content

Commit

Permalink
MDRAID: Finished proper bitmap generation
Browse files Browse the repository at this point in the history
Signed-off-by: Tomas Mudrunka <[email protected]>
  • Loading branch information
Harvie committed Dec 28, 2024
1 parent a423b56 commit 8573a5f
Showing 1 changed file with 13 additions and 7 deletions.
20 changes: 13 additions & 7 deletions image-mdraid.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
MDRAID Superblock generator
This should create valid mdraid superblock for raid1 with 1 device (more devices can be added once mounted).
Unlike mdadm this works completely in userspace and does not need kernel to create the ondisk structures.
It is still very basic, but following seems to be working:
mdadm --examine test.img
Expand All @@ -42,6 +43,7 @@ Some docs:

#define DATA_OFFSET_SECTORS (2048)
#define DATA_OFFSET_BYTES (DATA_OFFSET_SECTORS*512)
#define BITMAP_SECTORS_MAX 256
#define MDRAID_ALIGN_BYTES 8*512 //(should be divisible by 8 sectors to keep 4kB alignment)


Expand Down Expand Up @@ -150,7 +152,7 @@ static int mdraid_generate(struct image *image) {
/* constant array information - 128 bytes */
sb->magic = MD_SB_MAGIC; /* MD_SB_MAGIC: 0xa92b4efc - little endian. This is actualy just char string saying "bitm" :-) */
sb->major_version = 1; /* 1 */
sb->feature_map = 0; //MD_FEATURE_BITMAP_OFFSET; /* bit 0 set if 'bitmap_offset' is meaningful */ //TODO: internal bitmap bit is ignored, unless there is correct bitmap with BITMAP_MAGIC in place
sb->feature_map = MD_FEATURE_BITMAP_OFFSET; /* bit 0 set if 'bitmap_offset' is meaningful */ //TODO: internal bitmap bit is ignored, unless there is correct bitmap with BITMAP_MAGIC in place
sb->pad0 = 0; /* always set to 0 when writing */

char *raid_uuid = cfg_getstr(image->imagesec, "raid-uuid");
Expand Down Expand Up @@ -198,8 +200,7 @@ static int mdraid_generate(struct image *image) {
*/
sb->bblog_shift = 9; /* shift from sectors to block size */ //TODO: not sure why this is 9
sb->bblog_size = 8; /* number of sectors reserved for list */
sb->bblog_offset = 16; /* sector offset from superblock to bblog,
* signed - not unsigned */
sb->bblog_offset = sb->bitmap_offset+BITMAP_SECTORS_MAX+8; /* sector offset from superblock to bblog, signed - not unsigned */

/* array state information - 64 bytes */
sb->utime = sb->ctime; /* 40 bits second, 24 bits microseconds */
Expand All @@ -225,20 +226,25 @@ static int mdraid_generate(struct image *image) {

//Prepare bitmap superblock (bitmaps don't have checksums for performance reasons)
bsb.magic = BITMAP_MAGIC; /* 0 BITMAP_MAGIC */
bsb.version = 4; /* v4 is compatible with mdraid v1.2, 4 the bitmap major for now, could change... */ //FIXME: validate this!!!
memcpy(bsb.uuid, sb->device_uuid, sizeof(bsb.uuid)); /* 8 128 bit uuid - must match md device uuid */
bsb.version = 4; /* v4 is compatible with mdraid v1.2, 4 the bitmap major for now, could change... */
memcpy(bsb.uuid, sb->set_uuid, sizeof(bsb.uuid)); /* 8 128 bit uuid - must match md device uuid */
//bsb.events = 0; /* 24 event counter for the bitmap (1)*/
//bsb.events_cleared = 0;/*32 event counter when last bit cleared (2) */
bsb.sync_size = sb->data_size; /* 40 the size of the md device's sync range(3) */
//bsb.state = 0; /* 48 bitmap state information */
///bsb.chunksize; /* 52 the bitmap chunk size in bytes */
bsb.chunksize = 128*1024*512; /* 52 the bitmap chunk size in bytes, 65536KB seems to be default on linux */
bsb.daemon_sleep = 5; /* 5 is considered safe default. 56 seconds between disk flushes */
//bsb.write_behind = 0; /* 60 number of outstanding write-behind writes */
///bsb.sectors_reserved; /* 64 number of 512-byte sectors that are reserved for the bitmap. */
bsb.sectors_reserved = roundup(bsb.sync_size / bsb.chunksize, 8); /* 64 number of 512-byte sectors that are reserved for the bitmap. */
//bsb.nodes; /* 68 the maximum number of nodes in cluster. */
//bsb.cluster_name[64]; /* 72 cluster name to which this md belongs */
//__u8 pad[256 - 136]; /* set to zero */

//Increase bitmap chunk size till we fit in sectors max
while(bsb.sectors_reserved > BITMAP_SECTORS_MAX) {
bsb.chunksize *= 2;
bsb.sectors_reserved = roundup(bsb.sync_size / bsb.chunksize, 8);
}

//Construct image file
int ret;
Expand Down

0 comments on commit 8573a5f

Please sign in to comment.