]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libblkid: Add support for stratis
authorTony Asleson <tasleson@redhat.com>
Tue, 9 Jan 2018 21:08:12 +0000 (15:08 -0600)
committerKarel Zak <kzak@redhat.com>
Thu, 11 Jan 2018 09:08:24 +0000 (10:08 +0100)
Initial support for stratis, ref.
https://github.com/stratis-storage

[kzak@redhat.com: - remove C++ comment]

Signed-off-by: Tony Asleson <tasleson@redhat.com>
Signed-off-by: Karel Zak <kzak@redhat.com>
libblkid/src/Makemodule.am
libblkid/src/superblocks/stratis.c [new file with mode: 0644]
libblkid/src/superblocks/superblocks.c
libblkid/src/superblocks/superblocks.h

index 415c9f408c1be16beb33998c0273315d816a7695..65d2e66ed1dbd9b42ce1093781345da706201214 100644 (file)
@@ -82,6 +82,7 @@ libblkid_la_SOURCES = \
        libblkid/src/superblocks/romfs.c \
        libblkid/src/superblocks/silicon_raid.c \
        libblkid/src/superblocks/squashfs.c \
+       libblkid/src/superblocks/stratis.c \
        libblkid/src/superblocks/superblocks.c \
        libblkid/src/superblocks/superblocks.h \
        libblkid/src/superblocks/swap.c \
diff --git a/libblkid/src/superblocks/stratis.c b/libblkid/src/superblocks/stratis.c
new file mode 100644 (file)
index 0000000..96c7df9
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2018 Tony Asleson <tasleson@redhat.com>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+
+/*
+ * Specification for on disk format
+ * https://stratis-storage.github.io/StratisSoftwareDesign.pdf
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include "superblocks.h"
+#include "crc32c.h"
+
+struct stratis_sb {
+       uint32_t crc32;
+       uint8_t magic[16];
+       uint64_t sectors;
+       uint8_t reserved[4];
+       uint8_t pool_uuid[32];
+       uint8_t dev_uuid[32];
+       uint64_t mda_size;
+       uint64_t reserved_size;
+       uint64_t flags;
+       uint64_t initialization_time;
+} __attribute__ ((__packed__));
+
+#define BS 512
+#define FIRST_COPY_OFFSET BS
+#define SECOND_COPY_OFFSET (BS * 9)
+#define SB_AREA_SIZE (BS * 16)
+
+const char STRATIS_MAGIC[] = "!Stra0tis\x86\xff\x02^\x41rh";
+#define MAGIC_LEN (sizeof(STRATIS_MAGIC) - 1)
+
+#define _MAGIC_OFFSET (offsetof(const struct stratis_sb, magic))
+#define MAGIC_OFFSET_COPY_1 (FIRST_COPY_OFFSET + _MAGIC_OFFSET)
+#define MAGIC_OFFSET_COPY_2 (SECOND_COPY_OFFSET + _MAGIC_OFFSET)
+
+static int stratis_valid_sb(uint8_t *p)
+{
+       const struct stratis_sb *stratis = (const struct stratis_sb *)p;
+       uint32_t crc = 0;
+
+       /* generate CRC from byte position 4 for length 508 == 512 byte sector */
+       crc = crc32c(~0L, p + sizeof(stratis->crc32),
+                       BS - sizeof(stratis->crc32));
+       crc ^= ~0L;
+
+       return crc == le32_to_cpu(stratis->crc32);
+}
+
+static int probe_stratis(blkid_probe pr,
+               const struct blkid_idmag *mag __attribute__((__unused__)))
+{
+       const struct stratis_sb *stratis = NULL;
+       uint8_t *buf = blkid_probe_get_buffer(pr, 0, SB_AREA_SIZE);
+
+       if (!buf)
+               return errno ? -errno : 1;
+
+       if (stratis_valid_sb(buf + FIRST_COPY_OFFSET)) {
+               stratis = (const struct stratis_sb *)(buf + FIRST_COPY_OFFSET);
+       } else {
+               if (!stratis_valid_sb(buf + SECOND_COPY_OFFSET))
+                       return 1;
+
+               stratis = (const struct stratis_sb *)
+                               (buf + SECOND_COPY_OFFSET);
+       }
+
+       blkid_probe_strncpy_uuid(pr, (unsigned char *)stratis->dev_uuid,
+                                       sizeof(stratis->dev_uuid));
+       blkid_probe_set_value(pr, "POOL_UUID",
+                               (unsigned char *)stratis->pool_uuid,
+                               sizeof(stratis->pool_uuid));
+
+       blkid_probe_sprintf_value(pr, "BLOCKDEV_SECTORS", "%" PRIu64,
+                                       stratis->sectors);
+       blkid_probe_sprintf_value(pr, "BLOCKDEV_INITTIME", "%" PRIu64,
+                                       stratis->initialization_time);
+
+       return 0;
+}
+
+const struct blkid_idinfo stratis_idinfo = {
+       .name           = "stratis",
+       .usage          = BLKID_USAGE_RAID,
+       .probefunc      = probe_stratis,
+       .minsz          = SB_AREA_SIZE,
+       .magics         = {
+               { .magic = STRATIS_MAGIC, .len = MAGIC_LEN,
+                       .sboff = MAGIC_OFFSET_COPY_1},
+               { .magic = STRATIS_MAGIC, .len = MAGIC_LEN,
+                       .sboff = MAGIC_OFFSET_COPY_2},
+               { NULL }
+       }
+};
index 4387ab9e57895acbfdc657da777a4e5ce6aa325e..076541d1a9d3ed285ce1a6315be6c4e1ad829f98 100644 (file)
@@ -114,6 +114,7 @@ static const struct blkid_idinfo *idinfos[] =
        &vmfs_volume_idinfo,
        &ubi_idinfo,
        &vdo_idinfo,
+       &stratis_idinfo,
 
        /* Filesystems */
        &vfat_idinfo,
index 38f6a8a656d42bd24f130399fc6bb58321bca3d5..2723fb1d5682cf24667abb61852652aed10f3b8a 100644 (file)
@@ -80,6 +80,7 @@ extern const struct blkid_idinfo f2fs_idinfo;
 extern const struct blkid_idinfo bcache_idinfo;
 extern const struct blkid_idinfo mpool_idinfo;
 extern const struct blkid_idinfo vdo_idinfo;
+extern const struct blkid_idinfo stratis_idinfo;
 
 /*
  * superblock functions