1 /*
2 * Copyright (C) 2015 by Philipp Marek <philipp.marek@linbit.com>
3 *
4 * This file may be redistributed under the terms of the
5 * GNU Lesser General Public License.
6 *
7 * DRBD is a blocklevel replication solution in the Linux kernel,
8 * upstream since 2.6.33. (See http://drbd.linbit.com/)
9 * DRBDmanage is a configuration frontend that assists in
10 * creating/deleting/modifying DRBD resources across multiple machines
11 * (a DRBDmanage "cluster"); this file detects its control volume,
12 * which is replicated (via DRBD 9) on some of the nodes.
13 */
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <unistd.h>
17 #include <string.h>
18 #include <errno.h>
19 #include <ctype.h>
20 #include <inttypes.h>
21 #include <stddef.h>
22
23 #include "bitops.h"
24 #include "superblocks.h"
25
26 struct drbdmanage_hdr {
27 unsigned char magic[11];
28 unsigned char uuid[32];
29 unsigned char lf;
30 } __attribute__ ((packed));
31
32 struct drbdmanage_pers {
33 char magic[4];
34 uint32_t version_le;
35 } __attribute__ ((packed));
36
37
38 static const char persistence_magic[4] = { '\x1a', '\xdb', '\x98', '\xa2' };
39
40
41 static int probe_drbdmanage(blkid_probe pr,
42 const struct blkid_idmag *mag __attribute__((__unused__)))
43 {
44 struct drbdmanage_hdr *hdr;
45 unsigned char *cp;
46 struct drbdmanage_pers *prs;
47
48 hdr = (struct drbdmanage_hdr*)
49 blkid_probe_get_buffer(pr, 0, sizeof(*hdr));
50 if (!hdr)
51 return errno ? -errno : 1;
52
53 for(cp=hdr->uuid; cp<&hdr->lf; cp++)
54 if (!isxdigit(*cp))
55 return 1;
56 if (hdr->lf != '\n')
57 return 1;
58
59 if (blkid_probe_strncpy_uuid(pr,
60 hdr->uuid, sizeof(hdr->uuid)))
61 return errno ? -errno : 1;
62
63 prs = (struct drbdmanage_pers*)
64 blkid_probe_get_buffer(pr, 0x1000, sizeof(*prs));
65 if (!prs)
66 return errno ? -errno : 1;
67
68 if (memcmp(prs->magic, persistence_magic, sizeof(prs->magic)) == 0 &&
69 blkid_probe_sprintf_version(pr, "%d", be32_to_cpu(prs->version_le)) != 0)
70 return errno ? -errno : 1;
71
72 return 0;
73 }
74
75
76 const struct blkid_idinfo drbdmanage_idinfo =
77 {
78 .name = "drbdmanage_control_volume",
79 .usage = BLKID_USAGE_OTHER,
80 .probefunc = probe_drbdmanage,
81 .minsz = 64 * 1024,
82 .magics = {
83 { .magic = "$DRBDmgr=q", .len = 10, .sboff = 0 },
84 { NULL }
85 },
86 };
87