Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,24 @@
import yaml
import tempfile
import shutil
import stat


def resolve_block_device(label):
"""Resolve a label using an optional boot-time device map."""
path = '/run/onl/block-devices.json'
if not os.path.exists(path):
return subprocess.check_output(('blkid', '-L', label)).strip()

with open(path) as stream:
devices = json.load(stream)
if label not in devices:
# A device map is authoritative. Do not search other disks.
raise subprocess.CalledProcessError(2, ['blkid', '-L', label])
device = devices[label]
if not device.startswith('/dev/') or not stat.S_ISBLK(os.stat(device).st_mode):
raise ValueError('Invalid block device for %s: %s' % (label, device))
return device

class MountManager(object):

Expand Down Expand Up @@ -155,7 +173,7 @@ def _discover(k):
lbl = v.get('label', k)
useUbiDev = False
try:
v['device'] = subprocess.check_output(('blkid', '-L', lbl,)).strip()
v['device'] = resolve_block_device(lbl)
except subprocess.CalledProcessError:
useUbiDev = True
if useUbiDev == True:
Expand Down Expand Up @@ -443,7 +461,7 @@ def __init__(self, label, logger):
class OnlOnieBootContext(MountContext):
def __init__(self, mdir="/mnt/onie-boot", mode="rw", label="ONIE-BOOT", logger=None):
try:
device = subprocess.check_output("blkid -L %s" % label, shell=True).strip()
device = resolve_block_device(label)
except subprocess.CalledProcessError:
self.logger.debug("Block label %s does not yet exist..." % label)
raise
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1623,7 +1623,7 @@ CONFIG_BLK_DEV_MD=y
CONFIG_MD_AUTODETECT=y
# CONFIG_MD_LINEAR is not set
# CONFIG_MD_RAID0 is not set
# CONFIG_MD_RAID1 is not set
CONFIG_MD_RAID1=y
# CONFIG_MD_RAID10 is not set
# CONFIG_MD_RAID456 is not set
# CONFIG_MD_MULTIPATH is not set
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
src/lib/sbin/mdadm
src/lib/sbin/mdmon
src/lib/raid/COPYING.mdadm
builds/mdadm-*.tar.xz
builds/mdadm-*.tar.xz.part
builds/.mdadm-build/
__pycache__/
*.pyc
Original file line number Diff line number Diff line change
@@ -1 +1,33 @@
!include $ONL_TEMPLATES/platform-config-platform.yml ARCH=amd64 VENDOR=accton BASENAME=x86-64-accton-as9957-32db REVISION=r0
# Keep the RAID boot hooks local to this platform.
prerequisites:
packages:
- onl-vendor-config-accton:all
- onl-platform-modules-x86-64-accton-as9957-32db:amd64

common:
version: 1.0.0
arch: amd64
copyright: Copyright 2013, 2014, 2015 Big Switch Networks
maintainer: support@bigswitch.com
support: opennetworklinux@googlegroups.com
changelog: None
dists: $DISTS

packages:
- name: onl-platform-config-x86-64-accton-as9957-32db-r0
depends: onl-vendor-config-accton,onl-platform-modules-x86-64-accton-as9957-32db
summary: ONL Platform Configuration Package for x86-64-accton-as9957-32db-r0
# Copy the platform tree before placing the boot entry inside it.
files:
- src/lib: /lib/platform-config/x86-64-accton-as9957-32db-r0/onl
- src/python: ${PY_INSTALL}/onl/platform/
- src/boot/mdraid: /lib/platform-config/x86-64-accton-as9957-32db-r0/onl/boot/x86-64-accton-as9957-32db-r0
- src/boot.d/05.mdraid: /etc/boot.d/05.mdraid
- src/init.d/onl-mdraid-clean: /etc/init.d/onl-mdraid-clean
# Register the shutdown script when the package is configured.
after-install: $__DIR__/src/init.d/postinst

- name: onl-platform-build-x86-64-accton-as9957-32db-r0
summary: ONL Platform Build Package for x86-64-accton-as9957-32db-r0
optional-files:
builds: $$PKG_INSTALL
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
############################################################
#
# Static mdadm and mdmon for the RAID boot helper.
#
# Both tools are built from one pinned upstream release and are
# linked statically. The loader and the runtime system then use
# the same files, on every Debian release.
#
############################################################
MDADM_VERSION := 4.3
MDADM_ARCHIVE := mdadm-$(MDADM_VERSION).tar.xz
# From https://www.kernel.org/pub/linux/utils/raid/mdadm/sha256sums.asc
MDADM_SHA256 := 416727ae1f1080ea6e3090cea36dd076826fc369151e36ab736557ba92196f9f
MDADM_URL := https://www.kernel.org/pub/linux/utils/raid/mdadm/$(MDADM_ARCHIVE)
# Keep the upstream warnings, but do not stop on warnings from newer
# compilers. Build without libudev: a static libudev is usually not
# available, and only "mdadm --monitor" and waiting for udev use it.
# mdadm 4.3 still needs the libudev.h header to compile.
MDADM_CXFLAGS := -O2 -Wno-error -DNO_LIBUDEV

# ONL adds the sbin directory of the running platform to PATH, so
# "mdadm" and "mdmon" can be typed at the shell after login.
SBIN := ../src/lib/sbin
LICENSE := ../src/lib/raid/COPYING.mdadm
WORK := .mdadm-build
SOURCE := $(WORK)/mdadm-$(MDADM_VERSION)

.PHONY: all clean

all: $(SBIN)/mdmon

# Download the source if it is not here. A copy placed here by hand
# works without network access. Both are checked before the build.
$(MDADM_ARCHIVE):
wget -O $@.part $(MDADM_URL)
echo "$(MDADM_SHA256) $@.part" | sha256sum -c -
mv $@.part $@

# The loader has no C library for these tools, so they must be static.
# mdmon is installed last: it appears only after every check passed.
$(SBIN)/mdmon: $(MDADM_ARCHIVE) Makefile
echo "$(MDADM_SHA256) $(MDADM_ARCHIVE)" | sha256sum -c -
rm -rf $(WORK)
rm -f $(SBIN)/mdadm $(SBIN)/mdmon $(LICENSE)
mkdir -p $(WORK) $(SBIN)
tar -xf $(MDADM_ARCHIVE) -C $(WORK)
$(MAKE) -C $(SOURCE) CC=gcc CXFLAGS="$(MDADM_CXFLAGS)" LDFLAGS=-static RUN_DIR=/run/mdadm mdadm mdmon
strip $(SOURCE)/mdadm $(SOURCE)/mdmon
for tool in mdadm mdmon; do readelf -d $(SOURCE)/$$tool | grep -q "no dynamic section" || exit 1; done
$(SOURCE)/mdadm --version 2>&1 | grep -q "mdadm - v$(MDADM_VERSION) "
$(SOURCE)/mdmon --help 2>&1 | grep -q -- "--takeover"
cp $(SOURCE)/COPYING $(LICENSE)
install -m 0755 $(SOURCE)/mdadm $(SBIN)/mdadm
install -m 0755 $(SOURCE)/mdmon $(SBIN)/mdmon
rm -rf $(WORK)

# Other files in the sbin directory are not touched.
clean:
rm -rf $(WORK) $(MDADM_ARCHIVE).part
rm -f $(SBIN)/mdadm $(SBIN)/mdmon $(LICENSE)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/sh
# Finish the handover before ONL upgrades or mounts runtime filesystems.
[ -r /run/onl/mdraid.state ] || exit 0
while ! python "/lib/platform-config/$(cat /etc/onl/platform)/onl/raid/onl-mdraid.py" takeover; do
echo 'ONL mdraid: mdmon handover failed. Exit this shell after correcting the error.' >&2
/bin/sh -i
done
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/sh
# This hook runs before the loader checks or mounts ONL filesystems.
# Keep early RAID logs available before switching rootfs.
mdraid_log=/etc/onl/mdraid.log
if python "/lib/platform-config/$(cat /etc/onl/platform)/onl/raid/onl-mdraid.py" loader >"$mdraid_log" 2>&1; then
cat "$mdraid_log"
else
# Block raw-member label lookup by later programs such as onl-pki.
mkdir -p /run/onl && printf '{}\n' > /run/onl/block-devices.json
{
echo 'ONL mdraid: RAID setup failed.'
cat "$mdraid_log"
} > /etc/onl/abort
cat /etc/onl/abort >&2
fi
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/bin/sh
### BEGIN INIT INFO
# Provides: onl-mdraid-clean
# Required-Start:
# Required-Stop:
# Should-Stop: halt reboot kexec
# X-Stop-After: umountroot
# Default-Start:
# Default-Stop: 0 6
# Short-Description: Mark the boot RAID clean before halt or reboot
# Description: Only mdmon can write the RAID metadata. When the
# root filesystem is read-only, ask mdmon to mark the
# array clean, so the next boot needs no resync.
### END INIT INFO

[ "$1" = stop ] || exit 0
# This file exists only when the system was booted from the RAID.
[ -r /run/onl/mdraid.state ] || exit 0

mdadm="/lib/platform-config/$(cat /etc/onl/platform)/onl/sbin/mdadm"
if [ ! -x "$mdadm" ]; then
echo "ONL mdraid: $mdadm is missing. The next boot will resync the RAID." >&2
exit 0
fi

sync
# Stop a running check or resync, so that its position is saved too.
for action in /sys/block/md*/md/sync_action; do
if [ -w "$action" ]; then
echo idle > "$action" 2> /dev/null
fi
done
# mdadm waits for at most five seconds for each array.
if "$mdadm" --wait-clean --scan; then
echo 'ONL mdraid: RAID marked clean.'
else
echo 'ONL mdraid: RAID was not marked clean. The next boot will resync it.' >&2
sleep 1
fi
exit 0
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/sh
# Register the shutdown script by its LSB header. The "init:" key of
# onlpm is not used here: its script skips update-rc.d while the rootfs
# is built.
set -e
update-rc.d onl-mdraid-clean defaults > /dev/null
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/sh
# The existing loader boot command sources this hook before switch_root.
python "/lib/platform-config/$(cat /etc/onl/platform)/onl/raid/onl-mdraid.py" prepare-root || exit 1
Loading