/src/util-linux/libblkid/src/superblocks/drbd.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (C) 2009 by Bastian Friedrich <bastian.friedrich@collax.com> |
3 | | * |
4 | | * This file may be redistributed under the terms of the |
5 | | * GNU Lesser General Public License. |
6 | | * |
7 | | * defines, structs taken from drbd source; file names represent drbd source |
8 | | * files. |
9 | | */ |
10 | | #include <stdio.h> |
11 | | #include <stdlib.h> |
12 | | #include <unistd.h> |
13 | | #include <string.h> |
14 | | #include <errno.h> |
15 | | #include <ctype.h> |
16 | | #include <inttypes.h> |
17 | | #include <stddef.h> |
18 | | |
19 | | #include "superblocks.h" |
20 | | |
21 | | enum { |
22 | | DRBD_VERSION_08, |
23 | | DRBD_VERSION_09, |
24 | | }; |
25 | | |
26 | | /* |
27 | | * drbd/drbd_int.h |
28 | | */ |
29 | 0 | #define BM_BLOCK_SHIFT 12 /* 4k per bit */ |
30 | 0 | #define BM_BLOCK_SIZE (1<<BM_BLOCK_SHIFT) |
31 | | |
32 | | /* |
33 | | * user/drbdmeta.c |
34 | | * We support v08 and v09 |
35 | | */ |
36 | | #define DRBD_MD_MAGIC_08 "\x83\x74\x02\x6b" |
37 | | #define DRBD_MD_MAGIC_84_UNCLEAN "\x83\x74\x02\x6c" |
38 | | #define DRBD_MD_MAGIC_09 "\x83\x74\x02\x6d" |
39 | | /* there is no DRBD_MD_MAGIC_09_UNCLEAN */ |
40 | | |
41 | | /* |
42 | | * drbd/linux/drbd.h |
43 | | */ |
44 | | enum drbd_uuid_index { |
45 | | UI_CURRENT, |
46 | | UI_BITMAP, |
47 | | UI_HISTORY_START, |
48 | | UI_HISTORY_END, |
49 | | UI_SIZE, /* nl-packet: number of dirty bits */ |
50 | | UI_FLAGS, /* nl-packet: flags */ |
51 | | UI_EXTENDED_SIZE /* Everything. */ |
52 | | }; |
53 | | |
54 | | |
55 | | /* |
56 | | * Used by libblkid to avoid unnecessary padding at the end of the structs and |
57 | | * too large unused structs in memory. |
58 | | */ |
59 | | #define DRBD_MD_OFFSET 4096 |
60 | | |
61 | | /* |
62 | | * user/shared/drbdmeta.c |
63 | | * Minor modifications wrt. types |
64 | | */ |
65 | | struct md_on_disk_08 { |
66 | | uint64_t la_sect; /* last agreed size. */ |
67 | | uint64_t uuid[UI_SIZE]; /* UUIDs */ |
68 | | uint64_t device_uuid; |
69 | | uint64_t reserved_u64_1; |
70 | | uint32_t flags; |
71 | | uint32_t magic; |
72 | | uint32_t md_size_sect; |
73 | | int32_t al_offset; /* signed sector offset to this block */ |
74 | | uint32_t al_nr_extents; /* important for restoring the AL */ |
75 | | int32_t bm_offset; /* signed sector offset to the bitmap, from here */ |
76 | | uint32_t bm_bytes_per_bit; |
77 | | uint32_t reserved_u32[4]; |
78 | | |
79 | | unsigned char padding_start[0]; |
80 | | unsigned char padding_end[0] __attribute__((aligned(4096))); |
81 | | }; |
82 | | |
83 | | /* |
84 | | * linux/drbd.h, v9 only |
85 | | */ |
86 | | #define DRBD_PEERS_MAX 32 |
87 | | #define HISTORY_UUIDS DRBD_PEERS_MAX |
88 | | |
89 | | /* |
90 | | * drbd-headers/drbd_meta_data.h |
91 | | * Minor modifications wrt. types |
92 | | */ |
93 | | struct peer_dev_md_on_disk_9 { |
94 | | uint64_t bitmap_uuid; |
95 | | uint64_t bitmap_dagtag; |
96 | | uint32_t flags; |
97 | | int32_t bitmap_index; |
98 | | uint32_t reserved_u32[2]; |
99 | | } __attribute__((packed)); |
100 | | |
101 | | struct meta_data_on_disk_9 { |
102 | | uint64_t effective_size; /* last agreed size */ |
103 | | uint64_t current_uuid; |
104 | | uint64_t reserved_u64[4]; /* to have the magic at the same position as in v07, and v08 */ |
105 | | uint64_t device_uuid; |
106 | | uint32_t flags; /* MDF */ |
107 | | uint32_t magic; |
108 | | uint32_t md_size_sect; |
109 | | uint32_t al_offset; /* offset to this block */ |
110 | | uint32_t al_nr_extents; /* important for restoring the AL */ |
111 | | uint32_t bm_offset; /* offset to the bitmap, from here */ |
112 | | uint32_t bm_bytes_per_bit; /* BM_BLOCK_SIZE */ |
113 | | uint32_t la_peer_max_bio_size; /* last peer max_bio_size */ |
114 | | uint32_t bm_max_peers; |
115 | | int32_t node_id; |
116 | | |
117 | | /* see al_tr_number_to_on_disk_sector() */ |
118 | | uint32_t al_stripes; |
119 | | uint32_t al_stripe_size_4k; |
120 | | |
121 | | uint32_t reserved_u32[2]; |
122 | | |
123 | | struct peer_dev_md_on_disk_9 peers[DRBD_PEERS_MAX]; |
124 | | uint64_t history_uuids[HISTORY_UUIDS]; |
125 | | |
126 | | unsigned char padding_start[0]; |
127 | | unsigned char padding_end[0] __attribute__((aligned(4096))); |
128 | | } __attribute__((packed)); |
129 | | |
130 | | |
131 | | static int is_zero_padded(const unsigned char *padding_start, |
132 | | const unsigned char *padding_end) |
133 | 0 | { |
134 | 0 | for (; padding_start < padding_end; padding_start++) { |
135 | 0 | if (*padding_start != 0) |
136 | 0 | return 0; |
137 | 0 | } |
138 | 0 | return 1; |
139 | 0 | } |
140 | | |
141 | | static int probe_drbd_84(blkid_probe pr, const struct blkid_idmag *mag) |
142 | 0 | { |
143 | 0 | const struct md_on_disk_08 *md; |
144 | |
|
145 | 0 | md = blkid_probe_get_sb(pr, mag, struct md_on_disk_08); |
146 | 0 | if (!md) |
147 | 0 | return errno ? -errno : 1; |
148 | | |
149 | 0 | if (be32_to_cpu(read_unaligned_member(md, bm_bytes_per_bit)) != BM_BLOCK_SIZE) |
150 | 0 | return 1; |
151 | | |
152 | 0 | if (!is_zero_padded(member_ptr(md, padding_start), |
153 | 0 | member_ptr(md, padding_end))) |
154 | 0 | return 1; |
155 | | |
156 | | /* |
157 | | * DRBD does not have "real" uuids; the following resembles DRBD's |
158 | | * notion of uuids (64 bit, see struct above) |
159 | | */ |
160 | 0 | blkid_probe_sprintf_uuid(pr, |
161 | 0 | member_ptr(md, device_uuid), sizeof(md->device_uuid), |
162 | 0 | "%" PRIx64, be64_to_cpu(read_unaligned_member(md, device_uuid))); |
163 | |
|
164 | 0 | blkid_probe_set_version(pr, "v08"); |
165 | |
|
166 | 0 | return 0; |
167 | 0 | } |
168 | | |
169 | | static int probe_drbd_90(blkid_probe pr, const struct blkid_idmag *mag) |
170 | 0 | { |
171 | 0 | const struct meta_data_on_disk_9 *md; |
172 | |
|
173 | 0 | md = blkid_probe_get_sb(pr, mag, struct meta_data_on_disk_9); |
174 | 0 | if (!md) |
175 | 0 | return errno ? -errno : 1; |
176 | | |
177 | 0 | if (be32_to_cpu(read_unaligned_member(md, bm_bytes_per_bit)) != BM_BLOCK_SIZE) |
178 | 0 | return 1; |
179 | | |
180 | 0 | if (!is_zero_padded(member_ptr(md, padding_start), |
181 | 0 | member_ptr(md, padding_end))) |
182 | 0 | return 1; |
183 | | |
184 | | /* |
185 | | * DRBD does not have "real" uuids; the following resembles DRBD's |
186 | | * notion of uuids (64 bit, see struct above) |
187 | | */ |
188 | 0 | blkid_probe_sprintf_uuid(pr, |
189 | 0 | member_ptr(md, device_uuid), sizeof(md->device_uuid), |
190 | 0 | "%" PRIx64, be64_to_cpu(read_unaligned_member(md, device_uuid))); |
191 | |
|
192 | 0 | blkid_probe_set_version(pr, "v09"); |
193 | |
|
194 | 0 | return 0; |
195 | 0 | } |
196 | | |
197 | | static int probe_drbd(blkid_probe pr, const struct blkid_idmag *mag) |
198 | 0 | { |
199 | 0 | if (mag->hint == DRBD_VERSION_08) |
200 | 0 | return probe_drbd_84(pr, mag); |
201 | | |
202 | 0 | if (mag->hint == DRBD_VERSION_09) |
203 | 0 | return probe_drbd_90(pr, mag); |
204 | | |
205 | 0 | return 1; |
206 | 0 | } |
207 | | |
208 | | const struct blkid_idinfo drbd_idinfo = |
209 | | { |
210 | | .name = "drbd", |
211 | | .usage = BLKID_USAGE_RAID, |
212 | | .probefunc = probe_drbd, |
213 | | /* |
214 | | * Smaller ones are certainly not DRBD9 devices. |
215 | | * Recent utils even refuse to generate larger ones, |
216 | | * keep this as a sufficient lower bound. |
217 | | */ |
218 | | .minsz = 0x10000, |
219 | | .magics = { |
220 | | { |
221 | | .magic = DRBD_MD_MAGIC_08, |
222 | | .len = sizeof(DRBD_MD_MAGIC_08) - 1, |
223 | | .hint = DRBD_VERSION_08, |
224 | | .kboff = -(DRBD_MD_OFFSET >> 10), |
225 | | .sboff = offsetof(struct md_on_disk_08, magic), |
226 | | }, |
227 | | { |
228 | | .magic = DRBD_MD_MAGIC_84_UNCLEAN, |
229 | | .len = sizeof(DRBD_MD_MAGIC_84_UNCLEAN) - 1, |
230 | | .hint = DRBD_VERSION_08, |
231 | | .kboff = -(DRBD_MD_OFFSET >> 10), |
232 | | .sboff = offsetof(struct md_on_disk_08, magic), |
233 | | }, |
234 | | { |
235 | | .magic = DRBD_MD_MAGIC_09, |
236 | | .len = sizeof(DRBD_MD_MAGIC_09) - 1, |
237 | | .hint = DRBD_VERSION_09, |
238 | | .kboff = -(DRBD_MD_OFFSET >> 10), |
239 | | .sboff = offsetof(struct meta_data_on_disk_9, magic), |
240 | | }, |
241 | | { NULL } |
242 | | } |
243 | | }; |
244 | | |