]> git.ipfire.org Git - thirdparty/util-linux.git/blob - libblkid/src/superblocks/drbd.c
7f72eb13f3d0cb68eb674ff0a0fc4ffcd69dbeb0
[thirdparty/util-linux.git] / libblkid / src / superblocks / drbd.c
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 * user/drbdmeta.c
28 * We support v08 and v09
29 */
30 #define DRBD_MD_MAGIC_08 "\x83\x74\x02\x6b"
31 #define DRBD_MD_MAGIC_84_UNCLEAN "\x83\x74\x02\x6c"
32 #define DRBD_MD_MAGIC_09 "\x83\x74\x02\x6d"
33 /* there is no DRBD_MD_MAGIC_09_UNCLEAN */
34
35 /*
36 * drbd/linux/drbd.h
37 */
38 enum drbd_uuid_index {
39 UI_CURRENT,
40 UI_BITMAP,
41 UI_HISTORY_START,
42 UI_HISTORY_END,
43 UI_SIZE, /* nl-packet: number of dirty bits */
44 UI_FLAGS, /* nl-packet: flags */
45 UI_EXTENDED_SIZE /* Everything. */
46 };
47
48
49 /*
50 * Used by libblkid to avoid unnecessary padding at the end of the structs and
51 * too large unused structs in memory.
52 */
53 #define DRBD_MD_OFFSET 4096
54
55 /*
56 * user/shared/drbdmeta.c
57 * Minor modifications wrt. types
58 */
59 struct md_on_disk_08 {
60 uint64_t la_sect; /* last agreed size. */
61 uint64_t uuid[UI_SIZE]; /* UUIDs */
62 uint64_t device_uuid;
63 uint64_t reserved_u64_1;
64 uint32_t flags;
65 uint32_t magic;
66 uint32_t md_size_sect;
67 int32_t al_offset; /* signed sector offset to this block */
68 uint32_t al_nr_extents; /* important for restoring the AL */
69 int32_t bm_offset; /* signed sector offset to the bitmap, from here */
70 uint32_t bm_bytes_per_bit;
71 uint32_t reserved_u32[4];
72
73 /* Unnecessary for libblkid **
74 * char reserved[8 * 512 - (8*(UI_SIZE+3)+4*11)];
75 */
76 };
77
78 /*
79 * linux/drbd.h, v9 only
80 */
81 #define DRBD_PEERS_MAX 32
82 #define HISTORY_UUIDS DRBD_PEERS_MAX
83
84 /*
85 * drbd-headers/drbd_meta_data.h
86 * Minor modifications wrt. types
87 */
88 struct peer_dev_md_on_disk_9 {
89 uint64_t bitmap_uuid;
90 uint64_t bitmap_dagtag;
91 uint32_t flags;
92 int32_t bitmap_index;
93 uint32_t reserved_u32[2];
94 } __attribute__((packed));
95
96 struct meta_data_on_disk_9 {
97 uint64_t effective_size; /* last agreed size */
98 uint64_t current_uuid;
99 uint64_t reserved_u64[4]; /* to have the magic at the same position as in v07, and v08 */
100 uint64_t device_uuid;
101 uint32_t flags; /* MDF */
102 uint32_t magic;
103 uint32_t md_size_sect;
104 uint32_t al_offset; /* offset to this block */
105 uint32_t al_nr_extents; /* important for restoring the AL */
106 uint32_t bm_offset; /* offset to the bitmap, from here */
107 uint32_t bm_bytes_per_bit; /* BM_BLOCK_SIZE */
108 uint32_t la_peer_max_bio_size; /* last peer max_bio_size */
109 uint32_t bm_max_peers;
110 int32_t node_id;
111
112 /* see al_tr_number_to_on_disk_sector() */
113 uint32_t al_stripes;
114 uint32_t al_stripe_size_4k;
115
116 uint32_t reserved_u32[2];
117
118 struct peer_dev_md_on_disk_9 peers[DRBD_PEERS_MAX];
119 uint64_t history_uuids[HISTORY_UUIDS];
120
121 /* Unnecessary for libblkid **
122 * char padding[0] __attribute__((aligned(4096)));
123 */
124 } __attribute__((packed));
125
126
127 static int probe_drbd_84(blkid_probe pr, const struct blkid_idmag *mag)
128 {
129 const struct md_on_disk_08 *md;
130
131 md = blkid_probe_get_sb(pr, mag, struct md_on_disk_08);
132 if (!md)
133 return errno ? -errno : 1;
134
135 /*
136 * DRBD does not have "real" uuids; the following resembles DRBD's
137 * notion of uuids (64 bit, see struct above)
138 */
139 blkid_probe_sprintf_uuid(pr,
140 member_ptr(md, device_uuid), sizeof(md->device_uuid),
141 "%" PRIx64, be64_to_cpu(read_unaligned_member(md, device_uuid)));
142
143 blkid_probe_set_version(pr, "v08");
144
145 return 0;
146 }
147
148 static int probe_drbd_90(blkid_probe pr, const struct blkid_idmag *mag)
149 {
150 const struct meta_data_on_disk_9 *md;
151
152 md = blkid_probe_get_sb(pr, mag, struct meta_data_on_disk_9);
153 if (!md)
154 return errno ? -errno : 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 blkid_probe_sprintf_uuid(pr,
161 member_ptr(md, device_uuid), sizeof(md->device_uuid),
162 "%" PRIx64, be64_to_cpu(read_unaligned_member(md, device_uuid)));
163
164 blkid_probe_set_version(pr, "v09");
165
166 return 0;
167 }
168
169 static int probe_drbd(blkid_probe pr, const struct blkid_idmag *mag)
170 {
171 if (mag->hint == DRBD_VERSION_08)
172 return probe_drbd_84(pr, mag);
173
174 if (mag->hint == DRBD_VERSION_09)
175 return probe_drbd_90(pr, mag);
176
177 return 1;
178 }
179
180 const struct blkid_idinfo drbd_idinfo =
181 {
182 .name = "drbd",
183 .usage = BLKID_USAGE_RAID,
184 .probefunc = probe_drbd,
185 /*
186 * Smaller ones are certainly not DRBD9 devices.
187 * Recent utils even refuse to generate larger ones,
188 * keep this as a sufficient lower bound.
189 */
190 .minsz = 0x10000,
191 .magics = {
192 {
193 .magic = DRBD_MD_MAGIC_08,
194 .len = sizeof(DRBD_MD_MAGIC_08) - 1,
195 .hint = DRBD_VERSION_08,
196 .kboff = -(DRBD_MD_OFFSET >> 10),
197 .sboff = offsetof(struct md_on_disk_08, magic),
198 },
199 {
200 .magic = DRBD_MD_MAGIC_84_UNCLEAN,
201 .len = sizeof(DRBD_MD_MAGIC_84_UNCLEAN) - 1,
202 .hint = DRBD_VERSION_08,
203 .kboff = -(DRBD_MD_OFFSET >> 10),
204 .sboff = offsetof(struct md_on_disk_08, magic),
205 },
206 {
207 .magic = DRBD_MD_MAGIC_09,
208 .len = sizeof(DRBD_MD_MAGIC_09) - 1,
209 .hint = DRBD_VERSION_09,
210 .kboff = -(DRBD_MD_OFFSET >> 10),
211 .sboff = offsetof(struct meta_data_on_disk_9, magic),
212 },
213 { NULL }
214 }
215 };
216