Skip to content

Commit

Permalink
MDRAID Prepare infrastructure to inheriting metadata from one array c…
Browse files Browse the repository at this point in the history
…omponent to others

Signed-off-by: Tomas Mudrunka <tomas.mudrunka@gmail.com>
  • Loading branch information
Harvie committed Dec 30, 2024
1 parent f6bdf28 commit 6b07e1e
Showing 1 changed file with 57 additions and 31 deletions.
88 changes: 57 additions & 31 deletions image-mdraid.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ Some docs:

static time_t mdraid_time = 0; //Array creation timestamp has to be identical across all the raid members, so we share it between invocations


/*
* bitmap structures:
* Taken from Linux kernel drivers/md/md-bitmap.h
Expand Down Expand Up @@ -97,6 +96,13 @@ typedef struct bitmap_super_s {
* devices. For raid10 it is the size of the array.
*/

typedef struct mdraid_img_s {
struct image *img_data;
struct image *img_inherit;
struct mdp_superblock_1 *sb;
bitmap_super_t bsb;
} mdraid_img_t;


static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb)
{
Expand Down Expand Up @@ -131,7 +137,7 @@ static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb)
}

static int mdraid_generate(struct image *image) {
struct image *img_in = image->handler_priv;
mdraid_img_t *md = image->handler_priv;

char *name = cfg_getstr(image->imagesec, "label");
__le16 max_devices = cfg_getint(image->imagesec, "devices");
Expand All @@ -148,8 +154,8 @@ static int mdraid_generate(struct image *image) {
}

size_t superblock_size = sizeof(struct mdp_superblock_1) + max_devices*2;
struct mdp_superblock_1 *sb = xzalloc(superblock_size);
bitmap_super_t bsb = {0};
struct mdp_superblock_1 *sb = md->sb = xzalloc(superblock_size);
bitmap_super_t *bsb = &md->bsb;

/* constant array information - 128 bytes */
sb->magic = MD_SB_MAGIC; /* MD_SB_MAGIC: 0xa92b4efc - little endian. This is actualy just char string saying "bitm" :-) */
Expand Down Expand Up @@ -227,25 +233,25 @@ static int mdraid_generate(struct image *image) {
sb->sb_csum = calc_sb_1_csum(sb);

//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... */
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 = 64*1024*1024; /* 52 the bitmap chunk size in bytes, 64MB is 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 = 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 */
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... */
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 = 64*1024*1024; /* 52 the bitmap chunk size in bytes, 64MB is 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 = 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);
while(bsb->sectors_reserved > BITMAP_SECTORS_MAX) {
bsb->chunksize *= 2;
bsb->sectors_reserved = roundup(bsb->sync_size / bsb->chunksize, 8);
}

//Construct image file
Expand All @@ -257,21 +263,22 @@ static int mdraid_generate(struct image *image) {
if (ret) return ret;
//Write bitmap
if ( sb->feature_map & MD_FEATURE_BITMAP_OFFSET ) {
ret = insert_data(image, &bsb, imageoutfile(image), sizeof(bsb), (sb->super_offset + sb->bitmap_offset) * 512);
ret = insert_data(image, bsb, imageoutfile(image), sizeof(*bsb), (sb->super_offset + sb->bitmap_offset) * 512);
if (ret) return ret;
}
//Write data
if (img_in) {
ret = insert_image(image, img_in, img_in->size, DATA_OFFSET_BYTES, 0);
if (md->img_data) {
ret = insert_image(image, md->img_data, md->img_data->size, DATA_OFFSET_BYTES, 0);
if (ret) return ret;
}

free(sb);

return 0;
}

static int mdraid_setup(struct image *image, cfg_t *cfg) {
mdraid_img_t *md = xzalloc(sizeof(mdraid_img_t));
image->handler_priv = md;

if (!mdraid_time) {
mdraid_time = time(NULL);
srandom(mdraid_time); //For UUID generation
Expand All @@ -285,33 +292,51 @@ static int mdraid_setup(struct image *image, cfg_t *cfg) {
}

//Find data image to be put inside the array
struct image *img_in = NULL;
md->img_data = NULL;
char *src = cfg_getstr(image->imagesec, "image");
if (src) {
//Add data image as dependency (so it's built first)
struct partition *part;
part = xzalloc(sizeof *part);
part->image = src;
list_add_tail(&part->list, &image->partitions);

if (part->image) {
image_info(image, "MDRAID using data from: %s\n", part->image);
img_in = image_get(part->image); //TODO: will this work for pre-existing images not generated by genimage???
if (!img_in) {
md->img_data = image_get(part->image); //TODO: will this work for pre-existing images not generated by genimage???
if (!md->img_data) {
image_error(image, "MDRAID cannot get image definition: %s\n", part->image);
return 8;
}
if (image->size == 0)
image->size = roundup(img_in->size + DATA_OFFSET_BYTES, MDRAID_ALIGN_BYTES);
if (image->size < (img_in->size + DATA_OFFSET_BYTES)) {
image->size = roundup(md->img_data->size + DATA_OFFSET_BYTES, MDRAID_ALIGN_BYTES);
if (image->size < (md->img_data->size + DATA_OFFSET_BYTES)) {
image_error(image, "MDRAID image too small to fit %s\n", part->image);
return 3;
}
}
} else {
image_info(image, "MDRAID is created without data.\n");
}
image->handler_priv = img_in;

//Inherit config from master
char *inherit = cfg_getstr(image->imagesec, "inherit");
if (inherit) {
//Add inherit image as dependency (so it's built first)
struct partition *part;
part = xzalloc(sizeof *part);
part->image = inherit;
list_add_tail(&part->list, &image->partitions);

md->img_inherit = image_get(part->image);

if (md->img_inherit) {
image_error(image, "MDRAID will inherit array metadata config from: %s\n", part->image);
} else {
image_error(image, "MDRAID cannot find image config to inherit metadata from: %s\n", part->image);
return 9;
}
}

//Make sure size is aligned
if (image->size != roundup(image->size, MDRAID_ALIGN_BYTES)) {
Expand All @@ -331,6 +356,7 @@ static cfg_opt_t mdraid_opts[] = {
CFG_STR("raid-uuid", NULL, CFGF_NONE),
CFG_STR("disk-uuid", NULL, CFGF_NONE),
CFG_STR("image", NULL, CFGF_NONE),
CFG_STR("inherit", NULL, CFGF_NONE),
CFG_END()
};

Expand Down

0 comments on commit 6b07e1e

Please sign in to comment.