Commit | Line | Data |
---|---|---|
96422adb TM |
1 | /* MDRAID Superblock generator |
2 | This should create valid mdraid superblock for raid1 with 1 device. | |
3 | It is still work in progress, but following seems to be recognized: | |
4 | ||
5 | make mdraid | |
6 | ./mdraid > test.img | |
7 | mdadm --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 | ||
18 | void 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 | ||
26 | static 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 | ||
58 | int 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 | } |