summaryrefslogtreecommitdiffstats
path: root/libblkid/zfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'libblkid/zfs.c')
-rw-r--r--libblkid/zfs.c226
1 files changed, 0 insertions, 226 deletions
diff --git a/libblkid/zfs.c b/libblkid/zfs.c
deleted file mode 100644
index b96c5df45..000000000
--- a/libblkid/zfs.c
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright (C) 2009-2010 by Andreas Dilger <adilger@sun.com>
- *
- * This file may be redistributed under the terms of the
- * GNU Lesser General Public License.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <ctype.h>
-#include <inttypes.h>
-
-#include "superblocks.h"
-
-#define VDEV_LABEL_UBERBLOCK (128 * 1024ULL)
-#define VDEV_LABEL_NVPAIR ( 16 * 1024ULL)
-#define VDEV_LABEL_SIZE (256 * 1024ULL)
-
-/* #include <sys/uberblock_impl.h> */
-#define UBERBLOCK_MAGIC 0x00bab10c /* oo-ba-bloc! */
-struct zfs_uberblock {
- uint64_t ub_magic; /* UBERBLOCK_MAGIC */
- uint64_t ub_version; /* SPA_VERSION */
- uint64_t ub_txg; /* txg of last sync */
- uint64_t ub_guid_sum; /* sum of all vdev guids */
- uint64_t ub_timestamp; /* UTC time of last sync */
- char ub_rootbp; /* MOS objset_phys_t */
-} __attribute__((packed));
-
-#define ZFS_TRIES 64
-#define ZFS_WANT 4
-
-#define DATA_TYPE_UINT64 8
-#define DATA_TYPE_STRING 9
-
-struct nvpair {
- uint32_t nvp_size;
- uint32_t nvp_unkown;
- uint32_t nvp_namelen;
- char nvp_name[0]; /* aligned to 4 bytes */
- /* aligned ptr array for string arrays */
- /* aligned array of data for value */
-};
-
-struct nvstring {
- uint32_t nvs_type;
- uint32_t nvs_elem;
- uint32_t nvs_strlen;
- unsigned char nvs_string[0];
-};
-
-struct nvuint64 {
- uint32_t nvu_type;
- uint32_t nvu_elem;
- uint64_t nvu_value;
-};
-
-struct nvlist {
- uint32_t nvl_unknown[3];
- struct nvpair nvl_nvpair;
-};
-
-#define nvdebug(fmt, ...) do { } while(0)
-/*#define nvdebug(fmt, a...) printf(fmt, ##a)*/
-
-static void zfs_extract_guid_name(blkid_probe pr, loff_t offset)
-{
- struct nvlist *nvl;
- struct nvpair *nvp;
- size_t left = 4096;
- int found = 0;
-
- offset = (offset & ~(VDEV_LABEL_SIZE - 1)) + VDEV_LABEL_NVPAIR;
-
- /* Note that we currently assume that the desired fields are within
- * the first 4k (left) of the nvlist. This is true for all pools
- * I've seen, and simplifies this code somewhat, because we don't
- * have to handle an nvpair crossing a buffer boundary. */
- nvl = (struct nvlist *)blkid_probe_get_buffer(pr, offset, left);
- if (nvl == NULL)
- return;
-
- nvdebug("zfs_extract: nvlist offset %llu\n", offset);
-
- nvp = &nvl->nvl_nvpair;
- while (left > sizeof(*nvp) && nvp->nvp_size != 0 && found < 3) {
- int avail; /* tracks that name/value data fits in nvp_size */
- int namesize;
-
- nvp->nvp_size = be32_to_cpu(nvp->nvp_size);
- nvp->nvp_namelen = be32_to_cpu(nvp->nvp_namelen);
- avail = nvp->nvp_size - nvp->nvp_namelen - sizeof(*nvp);
-
- nvdebug("left %zd nvp_size %u\n", left, nvp->nvp_size);
- if (left < nvp->nvp_size || avail < 0)
- break;
-
- namesize = (nvp->nvp_namelen + 3) & ~3;
-
- nvdebug("nvlist: size %u, namelen %u, name %*s\n",
- nvp->nvp_size, nvp->nvp_namelen, nvp->nvp_namelen,
- nvp->nvp_name);
- if (strncmp(nvp->nvp_name, "name", nvp->nvp_namelen) == 0) {
- struct nvstring *nvs = (void *)(nvp->nvp_name+namesize);
-
- nvs->nvs_type = be32_to_cpu(nvs->nvs_type);
- nvs->nvs_strlen = be32_to_cpu(nvs->nvs_strlen);
- avail -= nvs->nvs_strlen + sizeof(*nvs);
- nvdebug("nvstring: type %u string %*s\n", nvs->nvs_type,
- nvs->nvs_strlen, nvs->nvs_string);
- if (nvs->nvs_type == DATA_TYPE_STRING && avail >= 0)
- blkid_probe_set_label(pr, nvs->nvs_string,
- nvs->nvs_strlen);
- found++;
- } else if (strncmp(nvp->nvp_name, "guid",
- nvp->nvp_namelen) == 0) {
- struct nvuint64 *nvu = (void *)(nvp->nvp_name+namesize);
- uint64_t nvu_value;
-
- memcpy(&nvu_value, &nvu->nvu_value, sizeof(nvu_value));
- nvu->nvu_type = be32_to_cpu(nvu->nvu_type);
- nvu_value = be64_to_cpu(nvu_value);
- avail -= sizeof(*nvu);
- nvdebug("nvuint64: type %u value %"PRIu64"\n",
- nvu->nvu_type, nvu_value);
- if (nvu->nvu_type == DATA_TYPE_UINT64 && avail >= 0)
- blkid_probe_sprintf_value(pr, "UUID_SUB",
- "%"PRIu64, nvu_value);
- found++;
- } else if (strncmp(nvp->nvp_name, "pool_guid",
- nvp->nvp_namelen) == 0) {
- struct nvuint64 *nvu = (void *)(nvp->nvp_name+namesize);
- uint64_t nvu_value;
-
- memcpy(&nvu_value, &nvu->nvu_value, sizeof(nvu_value));
- nvu->nvu_type = be32_to_cpu(nvu->nvu_type);
- nvu_value = be64_to_cpu(nvu_value);
- avail -= sizeof(*nvu);
- nvdebug("nvuint64: type %u value %"PRIu64"\n",
- nvu->nvu_type, nvu_value);
- if (nvu->nvu_type == DATA_TYPE_UINT64 && avail >= 0)
- blkid_probe_sprintf_uuid(pr, (unsigned char *)
- &nvu_value,
- sizeof(nvu_value),
- "%"PRIu64, nvu_value);
- found++;
- }
- if (left > nvp->nvp_size)
- left -= nvp->nvp_size;
- else
- left = 0;
- nvp = (struct nvpair *)((char *)nvp + nvp->nvp_size);
- }
-}
-
-#define zdebug(fmt, ...) do {} while(0)
-/*#define zdebug(fmt, a...) printf(fmt, ##a)*/
-
-/* ZFS has 128x1kB host-endian root blocks, stored in 2 areas at the start
- * of the disk, and 2 areas at the end of the disk. Check only some of them...
- * #4 (@ 132kB) is the first one written on a new filesystem. */
-static int probe_zfs(blkid_probe pr,
- const struct blkid_idmag *mag __attribute__((__unused__)))
-{
- uint64_t swab_magic = swab64(UBERBLOCK_MAGIC);
- struct zfs_uberblock *ub;
- int swab_endian;
- loff_t offset;
- int tried;
- int found;
-
- zdebug("probe_zfs\n");
- /* Look for at least 4 uberblocks to ensure a positive match */
- for (tried = found = 0, offset = VDEV_LABEL_UBERBLOCK;
- tried < ZFS_TRIES && found < ZFS_WANT;
- tried++, offset += 4096) {
- /* also try the second uberblock copy */
- if (tried == (ZFS_TRIES / 2))
- offset = VDEV_LABEL_SIZE + VDEV_LABEL_UBERBLOCK;
-
- ub = (struct zfs_uberblock *)
- blkid_probe_get_buffer(pr, offset,
- sizeof(struct zfs_uberblock));
- if (ub == NULL)
- return -1;
-
- if (ub->ub_magic == UBERBLOCK_MAGIC)
- found++;
-
- if ((swab_endian = (ub->ub_magic == swab_magic)))
- found++;
-
- zdebug("probe_zfs: found %s-endian uberblock at %llu\n",
- swab_endian ? "big" : "little", offset >> 10);
- }
-
- if (found < 4)
- return -1;
-
- /* If we found the 4th uberblock, then we will have exited from the
- * scanning loop immediately, and ub will be a valid uberblock. */
- blkid_probe_sprintf_version(pr, "%" PRIu64, swab_endian ?
- swab64(ub->ub_version) : ub->ub_version);
-
- zfs_extract_guid_name(pr, offset);
-
- if (blkid_probe_set_magic(pr, offset,
- sizeof(ub->ub_magic),
- (unsigned char *) &ub->ub_magic))
- return -1;
-
- return 0;
-}
-
-const struct blkid_idinfo zfs_idinfo =
-{
- .name = "zfs_member",
- .usage = BLKID_USAGE_RAID,
- .probefunc = probe_zfs,
- .minsz = 64 * 1024 * 1024,
- .magics = BLKID_NONE_MAGIC
-};
-