Merge pull request #546 from flatcar-linux/krnowak/fix-rules

Fix udev rules in mdadm and lvm2
This commit is contained in:
Krzesimir Nowak 2020-08-27 16:11:57 +02:00 committed by GitHub
commit 63813d3706
16 changed files with 1043 additions and 1 deletions

View File

@ -64,7 +64,6 @@
=sys-fs/btrfs-progs-4.19.1 ~arm64 =sys-fs/btrfs-progs-4.19.1 ~arm64
=sys-fs/cryptsetup-1.7.5 ~arm64 =sys-fs/cryptsetup-1.7.5 ~arm64
=sys-fs/lsscsi-0.28 ~arm64 =sys-fs/lsscsi-0.28 ~arm64
=sys-fs/mdadm-3.4 **
=sys-fs/multipath-tools-0.6.4-r1 ~arm64 =sys-fs/multipath-tools-0.6.4-r1 ~arm64
=sys-fs/quota-4.04-r1 ~arm64 =sys-fs/quota-4.04-r1 ~arm64
=sys-libs/binutils-libs-2.29.1-r1 ~arm64 =sys-libs/binutils-libs-2.29.1-r1 ~arm64

View File

@ -0,0 +1,12 @@
diff -ur LVM2.2.02.145/udev/11-dm-lvm.rules.in LVM2.2.02.145.new/udev/11-dm-lvm.rules.in
--- LVM2.2.02.145/udev/11-dm-lvm.rules.in 2016-03-04 19:03:30.000000000 +0100
+++ LVM2.2.02.145.new/udev/11-dm-lvm.rules.in 2020-08-25 12:01:32.235684488 +0200
@@ -37,8 +37,6 @@
ENV{DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG}=="1", GOTO="lvm_end"
-OPTIONS+="event_timeout=180"
-
# Do not create symlinks for inappropriate subdevices.
ENV{DM_LV_NAME}=="pvmove?*|?*_vorigin", GOTO="lvm_disable"
ENV{DM_LV_LAYER}=="?*", GOTO="lvm_disable"

View File

@ -0,0 +1,294 @@
# Copyright 1999-2016 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
EAPI=6
inherit autotools eutils linux-info multilib systemd toolchain-funcs udev flag-o-matic
DESCRIPTION="User-land utilities for LVM2 (device-mapper) software"
HOMEPAGE="https://sourceware.org/lvm2/"
SRC_URI="ftp://sourceware.org/pub/lvm2/${PN/lvm/LVM}.${PV}.tgz
ftp://sourceware.org/pub/lvm2/old/${PN/lvm/LVM}.${PV}.tgz"
LICENSE="GPL-2"
SLOT="0"
KEYWORDS="~alpha amd64 ~arm arm64 ~hppa ~ia64 ~mips ~ppc ~ppc64 ~s390 ~sh ~sparc ~x86 ~amd64-linux ~x86-linux"
IUSE="readline static static-libs systemd clvm cman corosync lvm1 lvm2create_initrd openais selinux +udev +thin device-mapper-only"
REQUIRED_USE="device-mapper-only? ( !clvm !cman !corosync !lvm1 !lvm2create_initrd !openais !thin )
systemd? ( udev )
clvm? ( !systemd )"
DEPEND_COMMON="
clvm? (
cman? ( =sys-cluster/cman-3* )
corosync? ( sys-cluster/corosync )
openais? ( sys-cluster/openais )
=sys-cluster/libdlm-3*
)
readline? ( sys-libs/readline:0= )
udev? ( >=virtual/libudev-208:=[static-libs?] )"
# /run is now required for locking during early boot. /var cannot be assumed to
# be available -- thus, pull in recent enough baselayout for /run.
# This version of LVM is incompatible with cryptsetup <1.1.2.
RDEPEND="${DEPEND_COMMON}
!<sys-apps/baselayout-2.2
!<sys-apps/openrc-0.11
!<sys-fs/cryptsetup-1.1.2
!!sys-fs/clvm
!!sys-fs/lvm-user
>=sys-apps/util-linux-2.16
lvm2create_initrd? ( sys-apps/makedev )
thin? ( >=sys-block/thin-provisioning-tools-0.3.0 )"
# note: thin- 0.3.0 is required to avoid --disable-thin_check_needs_check
# USE 'static' currently only works with eudev, bug 520450
DEPEND="${DEPEND_COMMON}
virtual/pkgconfig
>=sys-devel/binutils-2.20.1-r1
sys-devel/autoconf-archive
systemd? ( >=sys-apps/systemd-205:0= )
static? (
selinux? ( sys-libs/libselinux[static-libs] )
udev? ( >=sys-fs/eudev-3.1.2[static-libs] )
>=sys-apps/util-linux-2.16[static-libs]
)"
S=${WORKDIR}/${PN/lvm/LVM}.${PV}
PATCHES=(
# Gentoo specific modification(s):
"${FILESDIR}"/${PN}-2.02.129-example.conf.in.patch
# For upstream -- review and forward:
"${FILESDIR}"/${PN}-2.02.63-always-make-static-libdm.patch
"${FILESDIR}"/${PN}-2.02.56-lvm2create_initrd.patch
"${FILESDIR}"/${PN}-2.02.67-createinitrd.patch #301331
"${FILESDIR}"/${PN}-2.02.99-locale-muck.patch #330373
"${FILESDIR}"/${PN}-2.02.70-asneeded.patch # -Wl,--as-needed
"${FILESDIR}"/${PN}-2.02.139-dynamic-static-ldflags.patch #332905
"${FILESDIR}"/${PN}-2.02.129-static-pkgconfig-libs.patch #370217, #439414 + blkid
"${FILESDIR}"/${PN}-2.02.130-pthread-pkgconfig.patch #492450
"${FILESDIR}"/${PN}-2.02.145-mkdev.patch #580062
# Flatcar:
"${FILESDIR}"/${PN}-2.02.145-oneshot.patch # https://github.com/lvmteam/lvm2/pull/37
"${FILESDIR}"/${PN}-2.02.145-rules.patch # https://sourceware.org/git/?p=lvm2.git;a=commit;h=125f27ac37bc9b93cc96f64052b9681b3d479ee1
)
pkg_setup() {
local CONFIG_CHECK="~SYSVIPC"
if use udev; then
local WARNING_SYSVIPC="CONFIG_SYSVIPC:\tis not set (required for udev sync)\n"
if linux_config_exists; then
local uevent_helper_path=$(linux_chkconfig_string UEVENT_HELPER_PATH)
if [ -n "${uevent_helper_path}" ] && [ "${uevent_helper_path}" != '""' ]; then
ewarn "It's recommended to set an empty value to the following kernel config option:"
ewarn "CONFIG_UEVENT_HELPER_PATH=${uevent_helper_path}"
fi
fi
fi
check_extra_config
# 1. Genkernel no longer copies /sbin/lvm blindly.
if use static; then
elog "Warning, we no longer overwrite /sbin/lvm and /sbin/dmsetup with"
elog "their static versions. If you need the static binaries,"
elog "you must append .static to the filename!"
fi
}
src_prepare() {
default
sed -i \
-e "1iAR = $(tc-getAR)" \
-e "s:CC ?= @CC@:CC = $(tc-getCC):" \
make.tmpl.in || die #444082
sed -i -e '/FLAG/s:-O2::' configure{.in,} || die #480212
if use udev && ! use device-mapper-only; then
sed -i -e '/use_lvmetad =/s:0:1:' conf/example.conf.in || die #514196
elog "Notice that \"use_lvmetad\" setting is enabled with USE=\"udev\" in"
elog "/etc/lvm/lvm.conf, which will require restart of udev, lvm, and lvmetad"
elog "if it was previously disabled."
fi
sed -i -e "s:/usr/bin/true:$(type -P true):" scripts/blk_availability_systemd_red_hat.service.in || die #517514
# Without thin-privision-tools, there is nothing to install for target install_man7:
use thin || { sed -i -e '/^install_lvm2/s:install_man7::' man/Makefile.in || die; }
eautoreconf
}
src_configure() {
filter-flags -flto
local myconf=()
local buildmode
myconf+=( $(use_enable !device-mapper-only dmeventd) )
myconf+=( $(use_enable !device-mapper-only cmdlib) )
myconf+=( $(use_enable !device-mapper-only applib) )
myconf+=( $(use_enable !device-mapper-only fsadm) )
myconf+=( $(use_enable !device-mapper-only lvmetad) )
use device-mapper-only && myconf+=( --disable-udev-systemd-background-jobs )
# Most of this package does weird stuff.
# The build options are tristate, and --without is NOT supported
# options: 'none', 'internal', 'shared'
if use static; then
buildmode="internal"
# This only causes the .static versions to become available
myconf+=( --enable-static_link )
else
buildmode="shared"
fi
dmbuildmode=$(use !device-mapper-only && echo internal || echo none)
# dmeventd requires mirrors to be internal, and snapshot available
# so we cannot disable them
myconf+=( --with-mirrors=${dmbuildmode} )
myconf+=( --with-snapshots=${dmbuildmode} )
if use thin; then
myconf+=( --with-thin=internal --with-cache=internal )
local texec
for texec in check dump repair restore; do
myconf+=( --with-thin-${texec}="${EPREFIX}"/sbin/thin_${texec} )
myconf+=( --with-cache-${texec}="${EPREFIX}"/sbin/cache_${texec} )
done
else
myconf+=( --with-thin=none --with-cache=none )
fi
if use lvm1; then
myconf+=( --with-lvm1=${buildmode} )
else
myconf+=( --with-lvm1=none )
fi
# disable O_DIRECT support on hppa, breaks pv detection (#99532)
use hppa && myconf+=( --disable-o_direct )
if use clvm; then
myconf+=( --with-cluster=${buildmode} )
# 4-state! Make sure we get it right, per bug 210879
# Valid options are: none, cman, gulm, all
#
# 2009/02:
# gulm is removed now, now dual-state:
# cman, none
# all still exists, but is not needed
#
# 2009/07:
# TODO: add corosync and re-enable ALL
local clvmd=""
use cman && clvmd="cman"
#clvmd="${clvmd/cmangulm/all}"
use corosync && clvmd="${clvmd:+$clvmd,}corosync"
use openais && clvmd="${clvmd:+$clvmd,}openais"
[ -z "${clvmd}" ] && clvmd="none"
myconf+=( --with-clvmd=${clvmd} )
myconf+=( --with-pool=${buildmode} )
else
myconf+=( --with-clvmd=none --with-cluster=none )
fi
econf \
$(use_enable readline) \
$(use_enable selinux) \
--enable-pkgconfig \
--with-confdir="${EPREFIX}"/etc \
--exec-prefix="${EPREFIX}" \
--sbindir="${EPREFIX}/sbin" \
--with-staticdir="${EPREFIX}"/sbin \
--libdir="${EPREFIX}/$(get_libdir)" \
--with-usrlibdir="${EPREFIX}/usr/$(get_libdir)" \
--with-default-dm-run-dir=/run \
--with-default-run-dir=/run/lvm \
--with-default-locking-dir=/run/lock/lvm \
--with-default-pid-dir=/run \
$(use_enable udev udev_rules) \
$(use_enable udev udev_sync) \
$(use_with udev udevdir "$(get_udevdir)"/rules.d) \
$(use_enable systemd udev-systemd-background-jobs) \
--with-systemdsystemunitdir="$(systemd_get_systemunitdir)" \
${myconf[@]} \
CLDFLAGS="${LDFLAGS}"
}
src_compile() {
pushd include >/dev/null
emake
popd >/dev/null
if use device-mapper-only ; then
emake device-mapper
else
emake
emake CC="$(tc-getCC)" -C scripts lvm2_activation_generator_systemd_red_hat
fi
}
src_install() {
local inst
INSTALL_TARGETS="install install_tmpfiles_configuration"
# install systemd related files only when requested, bug #522430
use systemd && INSTALL_TARGETS="${INSTALL_TARGETS} install_systemd_units install_systemd_generators"
use device-mapper-only && INSTALL_TARGETS="install_device-mapper"
for inst in ${INSTALL_TARGETS}; do
emake DESTDIR="${D}" ${inst}
done
newinitd "${FILESDIR}"/device-mapper.rc-2.02.105-r2 device-mapper
newconfd "${FILESDIR}"/device-mapper.conf-1.02.22-r3 device-mapper
if use !device-mapper-only ; then
newinitd "${FILESDIR}"/dmeventd.initd-2.02.67-r1 dmeventd
newinitd "${FILESDIR}"/lvm.rc-2.02.116-r6 lvm
newconfd "${FILESDIR}"/lvm.confd-2.02.28-r2 lvm
newinitd "${FILESDIR}"/lvm-monitoring.initd-2.02.105-r2 lvm-monitoring
newinitd "${FILESDIR}"/lvmetad.initd-2.02.116-r3 lvmetad
fi
if use clvm; then
newinitd "${FILESDIR}"/clvmd.rc-2.02.39 clvmd
newconfd "${FILESDIR}"/clvmd.confd-2.02.39 clvmd
fi
if use static-libs; then
dolib.a libdm/ioctl/libdevmapper.a
dolib.a libdaemon/client/libdaemonclient.a #462908
#gen_usr_ldscript libdevmapper.so
dolib.a daemons/dmeventd/libdevmapper-event.a
#gen_usr_ldscript libdevmapper-event.so
else
rm -f "${ED}"usr/$(get_libdir)/{libdevmapper-event,liblvm2cmd,liblvm2app,libdevmapper}.a
fi
if use lvm2create_initrd; then
dosbin scripts/lvm2create_initrd/lvm2create_initrd
doman scripts/lvm2create_initrd/lvm2create_initrd.8
newdoc scripts/lvm2create_initrd/README README.lvm2create_initrd
fi
insinto /etc
doins "${FILESDIR}"/dmtab
dodoc README VERSION* WHATS_NEW WHATS_NEW_DM doc/*.{c,txt} conf/*.conf
}
pkg_postinst() {
ewarn "Make sure the \"lvm\" init script is in the runlevels:"
ewarn "# rc-update add lvm boot"
ewarn
ewarn "Make sure to enable lvmetad in /etc/lvm/lvm.conf if you want"
ewarn "to enable lvm autoactivation and metadata caching."
}
src_test() {
einfo "Tests are disabled because of device-node mucking, if you want to"
einfo "run tests, compile the package and see ${S}/tests"
}

View File

@ -0,0 +1,2 @@
DIST mdadm-4.1.tar.xz 440756 BLAKE2B df0506d937c2aa309d7c68804f66f7dcd51783288594bf746832311c64b8cf82004af4af5f246c5f9753f1de324ff7d49b5ee752d6a00ec03864f7885389706e SHA512 0859c5d3e786345d93ff2c3b291ca8866ba60f1375479e5b4d343124f6824140a8268d42b8ae603b069edba761aa30aaf20d49e9ec54dfcbad34bad3bea0e433
DIST mdadm_4.1-3.debian.tar.xz 89640 BLAKE2B 3cb5e42dcbd218a71e55127cecda6f2594a1b1691e17c05f52a8cd0ba05b556d2812772e53d78de025738d7c2de059df3f878b8290ba3906b3d75ef435bfb698 SHA512 e9b04abf195d7bda9fb0197eb926c01a69b879ef82c72af6497116cea9be8f0823408dddbe5c6c033f5fae554a8fec17299e361fa48045e033c87dcee1a0bb63

View File

@ -0,0 +1,7 @@
This is a fork of Gentoo's sys-fs/mdadm package. The main reason of
having this fork is to carry two patches that are already a part of
upstream, but the release didn't yet happen, and Gentoo does not carry
them either.
There is also a minor change to build this package by default for
arm64 without needing an entry in accept_keywords file.

View File

@ -0,0 +1,9 @@
# Based on Debian /etc/default/mdadm
# Gentoo comment: The cronjob checks for this value to decide to actually
# validate arrays. If missing, it does NOT actually do anything.
# AUTOCHECK:
# should mdadm run periodic redundancy checks over your arrays? See
# /etc/cron.weekly/mdadm
#AUTOCHECK=true

View File

@ -0,0 +1,31 @@
https://bugs.gentoo.org/580188
From 5c97e465b33bf8fefb17da7f553a1c3812e508d5 Mon Sep 17 00:00:00 2001
From: Mike Frysinger <vapier@gentoo.org>
Date: Tue, 19 Apr 2016 18:10:54 -0400
Subject: [PATCH] include sys/sysmacros.h for major/minor/makedev prototypes
These funcs are defined in sys/sysmacros.h, so include it for them.
It works today due to an implicit include by sys/types.h, but the
various Linux C libraries are moving away from that.
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
---
mdadm.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/mdadm.h b/mdadm.h
index d209488..b8767a7 100755
--- a/mdadm.h
+++ b/mdadm.h
@@ -33,6 +33,7 @@ extern __off64_t lseek64 __P ((int __fd, __off64_t __offset, int __whence));
# endif
#endif
+#include <sys/sysmacros.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdint.h>
--
2.7.4

View File

@ -0,0 +1,153 @@
From 8e1cd38c3b2be105fe2ef716c7cf1808cea2893c Mon Sep 17 00:00:00 2001
Message-Id: <8e1cd38c3b2be105fe2ef716c7cf1808cea2893c.1576149816.git.dongsu@kinvolk.io>
In-Reply-To: <0536ec52db8cf4f8aaf8bfc6abd51dde3a701f00.1576149816.git.dongsu@kinvolk.io>
References: <0536ec52db8cf4f8aaf8bfc6abd51dde3a701f00.1576149816.git.dongsu@kinvolk.io>
From: NeilBrown <neilb@suse.de>
Date: Mon, 4 Nov 2019 14:27:49 +1100
Subject: [PATCH 2/2] Assemble: add support for RAID0 layouts.
If you have a RAID0 array with varying sized devices
on a kernel before 5.4, you cannot assembling it on
5.4 or later without explicitly setting the layout.
This is now possible with
--update=layout-original (For 3.13 and earlier kernels)
or
--update=layout-alternate (for 3.14 and later kernels)
Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Assemble.c | 8 ++++++++
md.4 | 7 +++++++
mdadm.8.in | 17 +++++++++++++++++
mdadm.c | 4 ++++
super1.c | 12 +++++++++++-
5 files changed, 47 insertions(+), 1 deletion(-)
diff --git a/Assemble.c b/Assemble.c
index a79466c6..766f5acf 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -1028,6 +1028,11 @@ static int start_array(int mdfd,
pr_err("failed to add %s to %s: %s\n",
devices[j].devname, mddev,
strerror(errno));
+ if (errno == EINVAL && content->array.level == 0 &&
+ content->array.layout != 0) {
+ cont_err("Possibly your kernel doesn't support RAID0 layouts.\n");
+ cont_err("Please upgrade.\n");
+ }
if (i < content->array.raid_disks * 2 ||
i == bestcnt)
okcnt--;
@@ -1213,6 +1218,9 @@ static int start_array(int mdfd,
return 0;
}
pr_err("failed to RUN_ARRAY %s: %s\n", mddev, strerror(errno));
+ if (errno == 524 /* ENOTSUP */ &&
+ content->array.level == 0 && content->array.layout == 0)
+ cont_err("Please use --update=layout-original or --update=layout-alternate\n");
if (!enough(content->array.level, content->array.raid_disks,
content->array.layout, 1, avail))
diff --git a/md.4 b/md.4
index 22a0dd4d..952e67e2 100644
--- a/md.4
+++ b/md.4
@@ -208,6 +208,13 @@ array,
will record the chosen layout in the metadata in a way that allows newer
kernels to assemble the array without needing a module parameter.
+To assemble an old array on a new kernel without using the module parameter,
+use either the
+.B "--update=layout-original"
+option or the
+.B "--update=layout-alternate"
+option.
+
.SS RAID1
A RAID1 array is also known as a mirrored set (though mirrors tend to
diff --git a/mdadm.8.in b/mdadm.8.in
index fc9b6a66..6b63bb41 100644
--- a/mdadm.8.in
+++ b/mdadm.8.in
@@ -1213,6 +1213,8 @@ argument given to this flag can be one of
.BR no\-bbl ,
.BR ppl ,
.BR no\-ppl ,
+.BR layout\-original ,
+.BR layout\-alternate ,
.BR metadata ,
or
.BR super\-minor .
@@ -1364,6 +1366,21 @@ The
.B no\-ppl
option will disable PPL in the superblock.
+The
+.B layout\-original
+and
+.B layout\-alternate
+options are for RAID0 arrays in use before Linux 5.4. If the array was being
+used with Linux 3.13 or earlier, then to assemble the array on a new kernel,
+.B \-\-update=layout\-original
+must be given. If the array was created and used with a kernel from Linux 3.14 to
+Linux 5.3, then
+.B \-\-update=layout\-alternate
+must be given. This only needs to be given once. Subsequent assembly of the array
+will happen normally.
+For more information, see
+.IR md (4).
+
.TP
.BR \-\-freeze\-reshape
Option is intended to be used in start-up scripts during initrd boot phase.
diff --git a/mdadm.c b/mdadm.c
index 26faa47d..51aabe67 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -791,6 +791,9 @@ int main(int argc, char *argv[])
continue;
if (strcmp(c.update, "revert-reshape") == 0)
continue;
+ if (strcmp(c.update, "layout-original") == 0 ||
+ strcmp(c.update, "layout-alternate") == 0)
+ continue;
if (strcmp(c.update, "byteorder") == 0) {
if (ss) {
pr_err("must not set metadata type with --update=byteorder.\n");
@@ -821,6 +824,7 @@ int main(int argc, char *argv[])
" 'summaries', 'homehost', 'home-cluster', 'byteorder', 'devicesize',\n"
" 'no-bitmap', 'metadata', 'revert-reshape'\n"
" 'bbl', 'no-bbl', 'force-no-bbl', 'ppl', 'no-ppl'\n"
+ " 'layout-original', 'layout-alternate'\n"
);
exit(outf == stdout ? 0 : 2);
diff --git a/super1.c b/super1.c
index 654e605c..7cd4497a 100644
--- a/super1.c
+++ b/super1.c
@@ -1550,7 +1550,17 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
sb->devflags |= FailFast1;
else if (strcmp(update, "nofailfast") == 0)
sb->devflags &= ~FailFast1;
- else
+ else if (strcmp(update, "layout-original") == 0 ||
+ strcmp(update, "layout-alternate") == 0) {
+ if (__le32_to_cpu(sb->level) != 0) {
+ pr_err("%s: %s only supported for RAID0\n",
+ devname?:"", update);
+ rv = -1;
+ } else {
+ sb->feature_map |= __cpu_to_le32(MD_FEATURE_RAID0_LAYOUT);
+ sb->layout = __cpu_to_le32(update[7] == 'o' ? 1 : 2);
+ }
+ } else
rv = -1;
sb->sb_csum = calc_sb_1_csum(sb);
--
2.24.1

View File

@ -0,0 +1,343 @@
From 0536ec52db8cf4f8aaf8bfc6abd51dde3a701f00 Mon Sep 17 00:00:00 2001
Message-Id: <0536ec52db8cf4f8aaf8bfc6abd51dde3a701f00.1576149816.git.dongsu@kinvolk.io>
From: NeilBrown <neilb@suse.de>
Date: Mon, 4 Nov 2019 14:27:49 +1100
Subject: [PATCH 1/2] Create: add support for RAID0 layouts.
Since Linux 5.4 a layout is needed for RAID0 arrays with
varying device sizes.
This patch makes the layout of an array visible (via --examine)
and sets the layout on newly created arrays.
--layout=dangerous
can be used to avoid setting a layout so that they array
can be used on older kernels.
Tested-by: dann frazier <dann.frazier@canonical.com>
Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Create.c | 11 +++++++++++
Detail.c | 5 +++++
maps.c | 12 ++++++++++++
md.4 | 14 ++++++++++++++
mdadm.8.in | 30 +++++++++++++++++++++++++++++-
mdadm.c | 8 ++++++++
mdadm.h | 8 +++++++-
super0.c | 6 ++++++
super1.c | 30 +++++++++++++++++++++++++++++-
9 files changed, 121 insertions(+), 3 deletions(-)
diff --git a/Create.c b/Create.c
index 04b1dfc9..f4977cfe 100644
--- a/Create.c
+++ b/Create.c
@@ -39,6 +39,9 @@ static int default_layout(struct supertype *st, int level, int verbose)
default: /* no layout */
layout = 0;
break;
+ case 0:
+ layout = RAID0_ORIG_LAYOUT;
+ break;
case 10:
layout = 0x102; /* near=2, far=1 */
if (verbose > 0)
@@ -933,6 +936,11 @@ int Create(struct supertype *st, char *mddev,
if (rv) {
pr_err("ADD_NEW_DISK for %s failed: %s\n",
dv->devname, strerror(errno));
+ if (errno == EINVAL &&
+ info.array.level == 0) {
+ pr_err("Possibly your kernel doesn't support RAID0 layouts.\n");
+ pr_err("Either upgrade, or use --layout=dangerous\n");
+ }
goto abort_locked;
}
break;
@@ -1029,6 +1037,9 @@ int Create(struct supertype *st, char *mddev,
if (ioctl(mdfd, RUN_ARRAY, &param)) {
pr_err("RUN_ARRAY failed: %s\n",
strerror(errno));
+ if (errno == 524 /* ENOTSUP */ &&
+ info.array.level == 0)
+ cont_err("Please use --layout=original or --layout=alternate\n");
if (info.array.chunk_size & (info.array.chunk_size-1)) {
cont_err("Problem may be that chunk size is not a power of 2\n");
}
diff --git a/Detail.c b/Detail.c
index b3e857a7..ce69796f 100644
--- a/Detail.c
+++ b/Detail.c
@@ -515,6 +515,11 @@ int Detail(char *dev, struct context *c)
printf(" Layout : %s\n",
str ? str : "-unknown-");
}
+ if (array.level == 0 && array.layout) {
+ str = map_num(r0layout, array.layout);
+ printf(" Layout : %s\n",
+ str ? str : "-unknown-");
+ }
if (array.level == 6) {
str = map_num(r6layout, array.layout);
printf(" Layout : %s\n",
diff --git a/maps.c b/maps.c
index 02a04742..f143552f 100644
--- a/maps.c
+++ b/maps.c
@@ -73,6 +73,18 @@ mapping_t r6layout[] = {
{ NULL, UnSet }
};
+/* raid0 layout is only needed because of a bug in 3.14 which changed
+ * the effective layout of raid0 arrays with varying device sizes.
+ */
+mapping_t r0layout[] = {
+ { "original", RAID0_ORIG_LAYOUT},
+ { "alternate", RAID0_ALT_MULTIZONE_LAYOUT},
+ { "1", 1}, /* aka ORIG */
+ { "2", 2}, /* aka ALT */
+ { "dangerous", 0},
+ { NULL, UnSet},
+};
+
mapping_t pers[] = {
{ "linear", LEVEL_LINEAR},
{ "raid0", 0},
diff --git a/md.4 b/md.4
index 3a1d6777..22a0dd4d 100644
--- a/md.4
+++ b/md.4
@@ -193,6 +193,20 @@ smallest device has been exhausted, the RAID0 driver starts
collecting chunks into smaller stripes that only span the drives which
still have remaining space.
+A bug was introduced in linux 3.14 which changed the layout of blocks in
+a RAID0 beyond the region that is striped over all devices. This bug
+does not affect an array with all devices the same size, but can affect
+other RAID0 arrays.
+
+Linux 5.4 (and some stable kernels to which the change was backported)
+will not normally assemble such an array as it cannot know which layout
+to use. There is a module parameter "raid0.default_layout" which can be
+set to "1" to force the kernel to use the pre-3.14 layout or to "2" to
+force it to use the 3.14-and-later layout. when creating a new RAID0
+array,
+.I mdadm
+will record the chosen layout in the metadata in a way that allows newer
+kernels to assemble the array without needing a module parameter.
.SS RAID1
diff --git a/mdadm.8.in b/mdadm.8.in
index 9aec9f4f..fc9b6a66 100644
--- a/mdadm.8.in
+++ b/mdadm.8.in
@@ -593,6 +593,8 @@ to change the RAID level in some cases. See LEVEL CHANGES below.
This option configures the fine details of data layout for RAID5, RAID6,
and RAID10 arrays, and controls the failure modes for
.IR faulty .
+It can also be used for working around a kernel bug with RAID0, but generally
+doesn't need to be used explicitly.
The layout of the RAID5 parity block can be one of
.BR left\-asymmetric ,
@@ -652,7 +654,7 @@ option to set subsequent failure modes.
"clear" or "none" will remove any pending or periodic failure modes,
and "flush" will clear any persistent faults.
-Finally, the layout options for RAID10 are one of 'n', 'o' or 'f' followed
+The layout options for RAID10 are one of 'n', 'o' or 'f' followed
by a small number. The default is 'n2'. The supported options are:
.I 'n'
@@ -677,6 +679,32 @@ devices in the array. It does not need to divide evenly into that
number (e.g. it is perfectly legal to have an 'n2' layout for an array
with an odd number of devices).
+A bug introduced in Linux 3.14 means that RAID0 arrays
+.B "with devices of differing sizes"
+started using a different layout. This could lead to
+data corruption. Since Linux 5.4 (and various stable releases that received
+backports), the kernel will not accept such an array unless
+a layout is explictly set. It can be set to
+.RB ' original '
+or
+.RB ' alternate '.
+When creating a new array,
+.I mdadm
+will select
+.RB ' original '
+by default, so the layout does not normally need to be set.
+An array created for either
+.RB ' original '
+or
+.RB ' alternate '
+will not be recognized by an (unpatched) kernel prior to 5.4. To create
+a RAID0 array with devices of differing sizes that can be used on an
+older kernel, you can set the layout to
+.RB ' dangerous '.
+This will use whichever layout the running kernel supports, so the data
+on the array may become corrupt when changing kernel from pre-3.14 to a
+later kernel.
+
When an array is converted between RAID5 and RAID6 an intermediate
RAID6 layout is used in which the second parity block (Q) is always on
the last device. To convert a RAID5 to RAID6 and leave it in this new
diff --git a/mdadm.c b/mdadm.c
index 25a1abd2..26faa47d 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -546,6 +546,14 @@ int main(int argc, char *argv[])
pr_err("raid level must be given before layout.\n");
exit(2);
+ case 0:
+ s.layout = map_name(r0layout, optarg);
+ if (s.layout == UnSet) {
+ pr_err("layout %s not understood for raid0.\n",
+ optarg);
+ exit(2);
+ }
+ break;
case 5:
s.layout = map_name(r5layout, optarg);
if (s.layout == UnSet) {
diff --git a/mdadm.h b/mdadm.h
index 387e681a..83d630c4 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -731,7 +731,8 @@ extern int restore_stripes(int *dest, unsigned long long *offsets,
extern char *map_num(mapping_t *map, int num);
extern int map_name(mapping_t *map, char *name);
-extern mapping_t r5layout[], r6layout[], pers[], modes[], faultylayout[];
+extern mapping_t r0layout[], r5layout[], r6layout[],
+ pers[], modes[], faultylayout[];
extern mapping_t consistency_policies[], sysfs_array_states[];
extern char *map_dev_preferred(int major, int minor, int create,
@@ -1722,6 +1723,11 @@ char *xstrdup(const char *str);
#define makedev(M,m) (((M)<<8) | (m))
#endif
+enum r0layout {
+ RAID0_ORIG_LAYOUT = 1,
+ RAID0_ALT_MULTIZONE_LAYOUT = 2,
+};
+
/* for raid4/5/6 */
#define ALGORITHM_LEFT_ASYMMETRIC 0
#define ALGORITHM_RIGHT_ASYMMETRIC 1
diff --git a/super0.c b/super0.c
index 42989b9f..9adb3348 100644
--- a/super0.c
+++ b/super0.c
@@ -1291,6 +1291,12 @@ static int validate_geometry0(struct supertype *st, int level,
if (*chunk == UnSet)
*chunk = DEFAULT_CHUNK;
+ if (level == 0 && layout != UnSet) {
+ if (verbose)
+ pr_err("0.90 metadata does not support layouts for RAID0\n");
+ return 0;
+ }
+
if (!subdev)
return 1;
diff --git a/super1.c b/super1.c
index 636a2866..654e605c 100644
--- a/super1.c
+++ b/super1.c
@@ -43,7 +43,7 @@ struct mdp_superblock_1 {
__u64 ctime; /* lo 40 bits are seconds, top 24 are microseconds or 0*/
__u32 level; /* -4 (multipath), -1 (linear), 0,1,4,5 */
- __u32 layout; /* only for raid5 currently */
+ __u32 layout; /* used for raid5, raid6, raid10, and raid0 */
__u64 size; /* used size of component devices, in 512byte sectors */
__u32 chunksize; /* in 512byte sectors */
@@ -144,6 +144,7 @@ struct misc_dev_info {
#define MD_FEATURE_JOURNAL 512 /* support write journal */
#define MD_FEATURE_PPL 1024 /* support PPL */
#define MD_FEATURE_MUTLIPLE_PPLS 2048 /* support for multiple PPLs */
+#define MD_FEATURE_RAID0_LAYOUT 4096 /* layout is meaningful in RAID0 */
#define MD_FEATURE_ALL (MD_FEATURE_BITMAP_OFFSET \
|MD_FEATURE_RECOVERY_OFFSET \
|MD_FEATURE_RESHAPE_ACTIVE \
@@ -155,6 +156,7 @@ struct misc_dev_info {
|MD_FEATURE_JOURNAL \
|MD_FEATURE_PPL \
|MD_FEATURE_MULTIPLE_PPLS \
+ |MD_FEATURE_RAID0_LAYOUT \
)
static int role_from_sb(struct mdp_superblock_1 *sb)
@@ -498,6 +500,11 @@ static void examine_super1(struct supertype *st, char *homehost)
printf(" Events : %llu\n",
(unsigned long long)__le64_to_cpu(sb->events));
printf("\n");
+ if (__le32_to_cpu(sb->level) == 0 &&
+ (sb->feature_map & __cpu_to_le32(MD_FEATURE_RAID0_LAYOUT))) {
+ c = map_num(r0layout, __le32_to_cpu(sb->layout));
+ printf(" Layout : %s\n", c?c:"-unknown-");
+ }
if (__le32_to_cpu(sb->level) == 5) {
c = map_num(r5layout, __le32_to_cpu(sb->layout));
printf(" Layout : %s\n", c?c:"-unknown-");
@@ -1646,6 +1653,7 @@ struct devinfo {
int fd;
char *devname;
long long data_offset;
+ unsigned long long dev_size;
mdu_disk_info_t disk;
struct devinfo *next;
};
@@ -1687,6 +1695,7 @@ static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk,
di->devname = devname;
di->disk = *dk;
di->data_offset = data_offset;
+ get_dev_size(fd, NULL, &di->dev_size);
di->next = NULL;
*dip = di;
@@ -1888,10 +1897,25 @@ static int write_init_super1(struct supertype *st)
unsigned long long sb_offset;
unsigned long long data_offset;
long bm_offset;
+ int raid0_need_layout = 0;
for (di = st->info; di; di = di->next) {
if (di->disk.state & (1 << MD_DISK_JOURNAL))
sb->feature_map |= __cpu_to_le32(MD_FEATURE_JOURNAL);
+ if (sb->level == 0 && sb->layout != 0) {
+ struct devinfo *di2 = st->info;
+ unsigned long long s1, s2;
+ s1 = di->dev_size;
+ if (di->data_offset != INVALID_SECTORS)
+ s1 -= di->data_offset;
+ s1 /= __le32_to_cpu(sb->chunksize);
+ s2 = di2->dev_size;
+ if (di2->data_offset != INVALID_SECTORS)
+ s2 -= di2->data_offset;
+ s2 /= __le32_to_cpu(sb->chunksize);
+ if (s1 != s2)
+ raid0_need_layout = 1;
+ }
}
for (di = st->info; di; di = di->next) {
@@ -2039,6 +2063,10 @@ static int write_init_super1(struct supertype *st)
sb->bblog_offset = 0;
}
+ /* RAID0 needs a layout if devices aren't all the same size */
+ if (raid0_need_layout)
+ sb->feature_map |= __cpu_to_le32(MD_FEATURE_RAID0_LAYOUT);
+
sb->sb_csum = calc_sb_1_csum(sb);
rv = store_super1(st, di->fd);
--
2.24.1

View File

@ -0,0 +1,7 @@
# /etc/conf.d/mdadm: config file for /etc/init.d/mdadm
# Misc options to pass to mdadm in monitor mode.
# For more info, run `mdadm --monitor --help` or see
# the mdadm(8) manpage.
MDADM_OPTS="--syslog"

View File

@ -0,0 +1,25 @@
#!/sbin/openrc-run
# Copyright 1999-2006 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
depend() {
use logger dns net
}
start() {
ebegin "Starting mdadm monitor"
mdadm --monitor --scan \
--daemonise \
--pid-file /var/run/mdadm.pid \
${MDADM_OPTS}
eend $?
}
stop() {
local ret
ebegin "Stopping mdadm monitor"
start-stop-daemon --stop --pidfile /var/run/mdadm.pid
ret=$?
rm -f /var/run/mdadm.pid
eend ${ret}
}

View File

@ -0,0 +1,5 @@
#!/bin/sh
# This requires that AUTOCHECK is true in /etc/default/mdadm
if [ -x /usr/sbin/checkarray ] && [ $(date +\%d) -le 7 ]; then
/usr/sbin/checkarray --cron --all --idle --quiet
fi

View File

@ -0,0 +1,11 @@
# /etc/conf.d/mdraid: config file for /etc/init.d/mdraid
# For people who run raid on top of some other layer (like
# dmcrypt), use rc_need to specify that requirement. See
# the runscript(8) man page for more information.
# Most configuration happens in /etc/mdadm.conf.
# Pass additional options when assembling raids.
# Note: This applies to all raids.
MDADM_ASSEMBLE_OPTS=""

View File

@ -0,0 +1,39 @@
#!/sbin/openrc-run
# Copyright 1999-2015 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
depend() {
before checkfs fsck
after modules
}
start() {
local output
ebegin "Starting up RAID devices"
output=$(mdadm -As ${MDADM_ASSEMBLE_OPTS} 2>&1)
eend $? "${output}"
local pat="/dev/md_d*"
set -- ${pat}
if [ "$*" != "${pat}" ] ; then
ebegin "Creating RAID device partitions"
blockdev "$@"
eend $?
# wait because vgscan runs next, and we want udev to fire
sleep 1
fi
return 0
}
stop() {
local output
# XXX: Maybe drop this check ?
[ ! -e /etc/mdadm/mdadm.conf ] && [ ! -e /etc/mdadm.conf ] && return 0
ebegin "Shutting down RAID devices (mdadm)"
output=$(mdadm -Ss 2>&1)
eend $? "${output}"
}

View File

@ -0,0 +1,94 @@
# Copyright 1999-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
# Flatcar: Based on mdadm-4.1.ebuild from commit
# 32ddfce1d8ce63479d23d2983fa653ce5eac3ad2 in Gentoo repo (see
# https://gitweb.gentoo.org/repo/gentoo.git/plain/sys-fs/mdadm/mdadm-4.1.ebuild?id=32ddfce1d8ce63479d23d2983fa653ce5eac3ad2).
EAPI=6
inherit flag-o-matic multilib systemd toolchain-funcs udev
DESCRIPTION="Tool for running RAID systems - replacement for the raidtools"
HOMEPAGE="https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/"
DEB_PF="4.1-3"
SRC_URI="https://www.kernel.org/pub/linux/utils/raid/mdadm/${P/_/-}.tar.xz
mirror://debian/pool/main/m/mdadm/${PN}_${DEB_PF}.debian.tar.xz"
LICENSE="GPL-2"
SLOT="0"
# Flatcar: Build for arm64 too.
KEYWORDS="~alpha amd64 arm arm64 hppa ~ia64 ~mips ppc ppc64 sparc x86"
IUSE="static"
DEPEND="virtual/pkgconfig
app-arch/xz-utils"
RDEPEND=">=sys-apps/util-linux-2.16"
# The tests edit values in /proc and run tests on software raid devices.
# Thus, they shouldn't be run on systems with active software RAID devices.
RESTRICT="test"
PATCHES=(
"${FILESDIR}"/${PN}-3.4-sysmacros.patch #580188
# Flatcar: These patches are already upstreamed, but not released yet.
"${FILESDIR}"/${PN}-4.1-create-add-support-for-raid0-layouts.patch
"${FILESDIR}"/${PN}-4.1-assemble-add-support-for-raid0-layouts.patch
)
mdadm_emake() {
# We should probably make corosync & libdlm into USE flags. #573782
emake \
PKG_CONFIG="$(tc-getPKG_CONFIG)" \
CC="$(tc-getCC)" \
CWFLAGS="-Wall" \
CXFLAGS="${CFLAGS}" \
UDEVDIR="$(get_udevdir)" \
SYSTEMD_DIR="$(systemd_get_systemunitdir)" \
COROSYNC="-DNO_COROSYNC" \
DLM="-DNO_DLM" \
"$@"
}
src_compile() {
use static && append-ldflags -static
mdadm_emake all
}
src_test() {
mdadm_emake test
sh ./test || die
}
src_install() {
mdadm_emake DESTDIR="${D}" install install-systemd
dodoc ChangeLog INSTALL TODO README* ANNOUNCE-*
insinto /etc
newins mdadm.conf-example mdadm.conf
newinitd "${FILESDIR}"/mdadm.rc mdadm
newconfd "${FILESDIR}"/mdadm.confd mdadm
newinitd "${FILESDIR}"/mdraid.rc mdraid
newconfd "${FILESDIR}"/mdraid.confd mdraid
# From the Debian patchset
into /usr
dodoc "${WORKDIR}"/debian/README.checkarray
dosbin "${WORKDIR}"/debian/checkarray
insinto /etc/default
newins "${FILESDIR}"/etc-default-mdadm mdadm
exeinto /etc/cron.weekly
newexe "${FILESDIR}"/mdadm.weekly mdadm
}
pkg_postinst() {
if ! systemd_is_booted; then
if [[ -z ${REPLACING_VERSIONS} ]] ; then
# Only inform people the first time they install.
elog "If you're not relying on kernel auto-detect of your RAID"
elog "devices, you need to add 'mdraid' to your 'boot' runlevel:"
elog " rc-update add mdraid boot"
fi
fi
}

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE pkgmetadata SYSTEM "http://www.gentoo.org/dtd/metadata.dtd">
<pkgmetadata>
<maintainer type="project">
<email>base-system@gentoo.org</email>
<name>Gentoo Base System</name>
</maintainer>
<upstream>
<remote-id type="cpe">cpe:/a:mdadm_project:mdadm</remote-id>
</upstream>
</pkgmetadata>