MDRAID superblock generator
[mirrors/Programs.git] / c / mdraid-gen / mdraid.c
CommitLineData
96422adb
TM
1/* MDRAID Superblock generator
2This should create valid mdraid superblock for raid1 with 1 device.
3It is still work in progress, but following seems to be recognized:
4
5make mdraid
6./mdraid > test.img
7mdadm --examine test.img
8
9*/
10
11//#include <cstddef>
12#include <string.h>
13#include <time.h>
14#include <stdlib.h>
15#include <stdio.h>
16#include <linux/raid/md_p.h>
17
18void random_uuid(__u8 *buf)
19{
20 __u32 r[4];
21 for (int i = 0; i < 4; i++)
22 r[i] = random();
23 memcpy(buf, r, 16);
24}
25
26static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb)
27{
28 unsigned int disk_csum, csum;
29 unsigned long long newcsum;
30 int size = sizeof(*sb) + __le32_to_cpu(sb->max_dev)*2;
31 unsigned int *isuper = (unsigned int*)sb;
32
33/* make sure I can count... (needs include cstddef) */
34/*
35 if (offsetof(struct mdp_superblock_1,data_offset) != 128 ||
36 offsetof(struct mdp_superblock_1, utime) != 192 ||
37 sizeof(struct mdp_superblock_1) != 256) {
38 fprintf(stderr, "WARNING - superblock isn't sized correctly\n");
39 }
40*/
41
42 disk_csum = sb->sb_csum;
43 sb->sb_csum = 0;
44 newcsum = 0;
45 for (; size>=4; size -= 4 ) {
46 newcsum += __le32_to_cpu(*isuper);
47 isuper++;
48 }
49
50 if (size == 2)
51 newcsum += __le16_to_cpu(*(unsigned short*) isuper);
52
53 csum = (newcsum & 0xffffffff) + (newcsum >> 32);
54 sb->sb_csum = disk_csum;
55 return __cpu_to_le32(csum);
56}
57
58int main() {
59 srand(time(NULL)); //FIXME: Seed UUID properly
60
61 struct mdp_superblock_1 sb = {0};
62
63 /* constant array information - 128 bytes */
64 sb.magic = 0xa92b4efc; /* MD_SB_MAGIC: 0xa92b4efc - little endian */
65 sb.major_version = 1; /* 1 */
66 sb.feature_map = 0; /* bit 0 set if 'bitmap_offset' is meaningful */
67 sb.pad0 = 0; /* always set to 0 when writing */
68
69 //TODO: set these
70 random_uuid(sb.set_uuid); /* user-space generated. U8[16]*/
71 memcpy(sb.set_name, "localhost:777", 6); /* set and interpreted by user-space. CHAR[32] */
72 sb.ctime=0; /* lo 40 bits are seconds, top 24 are microseconds or 0*/
73
74 sb.level=1; /* -4 (multipath), -1 (linear), 0,1,4,5 */
75 sb.layout=2; /* only for raid5 and raid10 currently */
76 sb.size; /* used size of component devices, in 512byte sectors */
77
78 sb.chunksize=0; /* in 512byte sectors - not used in raid 1 */
79 sb.raid_disks=1;
80 sb.bitmap_offset=0; /* sectors after start of superblock that bitmap starts
81 * NOTE: signed, so bitmap can be before superblock
82 * only meaningful of feature_map[0] is set.
83 */
84
85 /* constant this-device information - 64 bytes */
86 sb.data_offset=4096+sizeof(sb); /* sector start of data, often 0 */
87 sb.data_size; /* sectors in this device that can be used for data */
88 sb.super_offset=8; /* sector start of this superblock */
89
90 sb.dev_number=0; /* permanent identifier of this device - not role in raid */
91 sb.cnt_corrected_read=0; /* number of read errors that were corrected by re-writing */
92 random_uuid(sb.device_uuid); /* user-space setable, ignored by kernel U8[16] */
93 sb.devflags=0; /* per-device flags. Only two defined...*/
94 //#define WriteMostly1 1 /* mask for writemostly flag in above */
95 //#define FailFast1 2 /* Should avoid retries and fixups and just fail */
96
97 /* array state information - 64 bytes */
98 sb.utime=0; /* 40 bits second, 24 bits microseconds */
99 sb.events=0; /* incremented when superblock updated */
100 sb.resync_offset=0; /* data before this offset (from data_offset) known to be in sync */
101 sb.max_dev=1; /* size of devs[] array to consider */
102 //__u8 pad3[64-32]; /* set to 0 when writing */
103
104 /* device state information. Indexed by dev_number.
105 * 2 bytes per device
106 * Note there are no per-device state flags. State information is rolled
107 * into the 'roles' value. If a device is spare or faulty, then it doesn't
108 * have a meaningful role.
109 */
110 //__le16 dev_roles[]; /* role in array, or 0xffff for a spare, or 0xfffe for faulty */
111
112
113 sb.sb_csum=calc_sb_1_csum(&sb);
114
115 //printf("Superblock\n");
116 for(int i=0;i<4096;i++) putc(0, stdout);
117 fwrite(&sb, sizeof(sb), 1, stdout);
118 for(int i=0;i<40960;i++) putc(0, stdout);
119}
This page took 0.25255 seconds and 4 git commands to generate.