Package: lvm2 Version: 2.02.95-4 Tags: patch wheezy sid Severity: important
Currently, lvm automatically filters out mdraid devices. That is a good thing, otherwise it could accidentally activate volume groups on disks that are part of a mdraid array. For quite some time now, the mdraid subsystem (mainly through mdadm) supports more metadata formats than native mdraid only. These are the 'imsm' (Intel Matrix Raid) and 'ddf' formats. This patch makes sure that disks with signatures of one of these metadata formats are also filtered out. To minimize the chance of regressions, it only does this if md is actually running (i.e. /proc/mdstat is present). Background: I have added support for installation on Intel Matrix raid (imsm) arrays using mdadm to d-i, and I'll be sending patches to the debian-boot list soon. Please consider this patch for inclusion in wheezy. Changelog entry: * lvm already filters disks that have a mdraid signature, now also filter DDF and IMSM formatted disks as well - but only if MD is actually running. Mike.
Description: Also automatically filter DDF and IMSM formatted disks Author: Miquel van Smoorenburg <miqu...@debian.org> --- lvm2-2.02.95.orig/lib/device/dev-md.c +++ lvm2-2.02.95/lib/device/dev-md.c @@ -16,6 +16,7 @@ #include "lib.h" #include "metadata.h" #include "xlate.h" +#include "crc.h" #include "filter.h" #ifdef linux @@ -29,6 +30,18 @@ - MD_RESERVED_SECTORS) #define MD_MAX_SYSFS_SIZE 64 +#define IMSM_SIGNATURE "Intel Raid ISM Cfg Sig. " +#define IMSM_SIG_LEN (strlen(IMSM_SIGNATURE)) + +#define DDF_MAGIC 0xDE11DE11 +struct ddf_header { + uint32_t magic; + uint32_t crc; + char guid[24]; + char revision[8]; + char padding[472]; +}; + static int _dev_has_md_magic(struct device *dev, uint64_t sb_offset) { uint32_t md_magic; @@ -42,6 +55,34 @@ static int _dev_has_md_magic(struct devi return 0; } +static int _dev_has_imsm_superblock(struct device *dev, uint64_t dev_size) +{ + char imsm_signature[IMSM_SIG_LEN]; + + if (dev_read(dev, dev_size - 1024, IMSM_SIG_LEN, imsm_signature) && + memcmp(imsm_signature, IMSM_SIGNATURE, IMSM_SIG_LEN) == 0) + return 1; + + return 0; +} + +static int _dev_has_ddf_superblock(struct device *dev, uint64_t dev_size) +{ + struct ddf_header hdr; + uint32_t crc; + + /* Also calculate CRC so we have at least 8 bytes to check */ + if (dev_read(dev, dev_size - 512, 512, &hdr) && + (hdr.magic == xlate32(DDF_MAGIC))) { + crc = hdr.crc; + hdr.crc = 0xffffffff; + if (xlate32(calc_crc(0, (const uint8_t *)&hdr, 512)) == crc) + return 1; + } + + return 0; +} + /* * Calculate the position of the superblock. * It is always aligned to a 4K boundary and @@ -86,6 +127,7 @@ int dev_is_md(struct device *dev, uint64 int ret = 1; md_minor_version_t minor; uint64_t size, sb_offset; + struct stat st; if (!dev_get_size(dev, &size)) { stack; @@ -114,6 +156,18 @@ int dev_is_md(struct device *dev, uint64 goto out; } while (++minor <= MD_MINOR_VERSION_MAX); + /* Only check for ddf/imsm if md is actually running. */ + if (stat("/proc/mdstat", &st) < 0) + goto out; + + /* Check if it is a ddf container device */ + if (_dev_has_ddf_superblock(dev, size)) + goto out; + + /* Check if it is an imsm container device */ + if (_dev_has_imsm_superblock(dev, size)) + goto out; + ret = 0; out: