Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/distrib zfs: build a ramdisk on amd64 with enough to mount r...



details:   https://anonhg.NetBSD.org/src/rev/5ecb63c0e2d9
branches:  trunk
changeset: 745060:5ecb63c0e2d9
user:      roy <roy%NetBSD.org@localhost>
date:      Sat Feb 22 09:53:47 2020 +0000

description:
zfs: build a ramdisk on amd64 with enough to mount rpool/ROOT on /

Until we get ZFS integrated into our boot loader, this is the next best
thing. The idea is simple - have a small FFS partition with a kernel,
modules and this ramdisk. Once the ramdisk boots it will mount the FFS
partition read only, copy the needed ZFS modules to the ramdisk and then
unmount the partition. Then we import the ZFS root pool, mount the
ZFS root filesystem and then pivot to it.

Because the initial FFS partition is not mounted at this point, we
can mount it in /altroot so we can replace the kernel and modules with
newer ones so it's easily maintainable.

This ZFS boot strapper currently makes the following assumptions:
 * The device NAME=boot is the FFS with kernel, modules and this ramdisk.
 * The ZFS root pool and root filesystem are called rpool/ROOT.

A boot.cfg menu entry can then be added like so:
menu=Boot ZFS root:fs /ramdisk-zfsroot.fs;boot

diffstat:

 distrib/amd64/ramdisks/ramdisk-zfsroot/Makefile |  17 ++++++
 distrib/amd64/ramdisks/ramdisk-zfsroot/list     |  12 ++++
 distrib/common/list.zfsroot                     |  29 +++++++++++
 distrib/common/mtree.zfsroot                    |   8 +++
 distrib/common/zfsroot.rc                       |  64 +++++++++++++++++++++++++
 5 files changed, 130 insertions(+), 0 deletions(-)

diffs (150 lines):

diff -r 4473a4ade91f -r 5ecb63c0e2d9 distrib/amd64/ramdisks/ramdisk-zfsroot/Makefile
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/distrib/amd64/ramdisks/ramdisk-zfsroot/Makefile   Sat Feb 22 09:53:47 2020 +0000
@@ -0,0 +1,17 @@
+#      $NetBSD: Makefile,v 1.1 2020/02/22 09:53:47 roy Exp $
+
+IMAGE=                 ramdisk-zfsroot.fs
+IMAGESIZE=             5000k
+IMAGEDEPENDS=
+MAKEDEVTARGETS=                all
+CRUNCHENV=             INIT_CHROOT=1
+SMALLPROG_INET6=       1
+
+LISTS+=                        ${DISTRIBDIR}/common/list.zfsroot
+
+.include "${.CURDIR}/../common/Makefile.ramdisk"
+.include "${DISTRIBDIR}/common/Makefile.makedev"
+
+LISTS+=                        ${.CURDIR}/list
+
+MTREECONF+=            ${DISTRIBDIR}/common/mtree.zfsroot
diff -r 4473a4ade91f -r 5ecb63c0e2d9 distrib/amd64/ramdisks/ramdisk-zfsroot/list
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/distrib/amd64/ramdisks/ramdisk-zfsroot/list       Sat Feb 22 09:53:47 2020 +0000
@@ -0,0 +1,12 @@
+#      $NetBSD: list,v 1.1 2020/02/22 09:53:47 roy Exp $
+
+PROG   bin/sync
+
+PROG   sbin/fdisk
+PROG   sbin/gpt
+PROG   sbin/mbrlabel
+PROG   sbin/shutdown
+
+PROG   usr/bin/less    usr/bin/more
+
+PROG   usr/sbin/installboot
diff -r 4473a4ade91f -r 5ecb63c0e2d9 distrib/common/list.zfsroot
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/distrib/common/list.zfsroot       Sat Feb 22 09:53:47 2020 +0000
@@ -0,0 +1,29 @@
+#      $NetBSD: list.zfsroot,v 1.1 2020/02/22 09:53:47 roy Exp $
+#
+# list file (c.f. parselist.awk) for ZFS on root.
+#
+
+SRCDIRS        external/cddl/osnet/sbin
+PROG   sbin/zfs
+PROG   sbin/zpool
+LINK   sbin/zfs sbin/mount_zfs
+ARGVLN zfs mount_zfs
+
+# We need sysctl to set init.root=/altroot
+PROG   sbin/sysctl
+
+LIBS   -lnvpair
+LIBS   -luutil
+LIBS   -lzfs
+LIBS   -lavl
+LIBS   -lm
+LIBS   -lpthread
+LIBS   -lumem
+#LIBS  -lutil          # replaced by libhack
+LIBS   -lz
+LIBS   -lzfs_core
+
+COPY   ${NETBSDSRCDIR}/distrib/common/zfsroot.rc etc/rc
+
+# Make firmware images available.
+SYMLINK        altroot/libdata libdata
diff -r 4473a4ade91f -r 5ecb63c0e2d9 distrib/common/mtree.zfsroot
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/distrib/common/mtree.zfsroot      Sat Feb 22 09:53:47 2020 +0000
@@ -0,0 +1,8 @@
+#      $NetBSD: mtree.zfsroot,v 1.1 2020/02/22 09:53:47 roy Exp $
+
+.
+./altroot
+./etc
+./etc/zfs
+./rpool
+./stand
diff -r 4473a4ade91f -r 5ecb63c0e2d9 distrib/common/zfsroot.rc
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/distrib/common/zfsroot.rc Sat Feb 22 09:53:47 2020 +0000
@@ -0,0 +1,64 @@
+#/bin/sh
+#
+#      $NetBSD: zfsroot.rc,v 1.1 2020/02/22 09:53:47 roy Exp $
+#      ZFS on Root boot strapper
+
+# Configurable - define the ZFS root pool and ROOT.
+# XXX Can these be set in boot.cfg?
+# Assumption - the root pool is set to legacy mount.
+rpool=rpool
+rroot=ROOT
+
+# Assumption - the boot device is named boot.
+# Could use dk0, wd0a, etc instead.
+# XXX Can be exposed by sysctl kern.boot_device?
+bootdev="NAME=boot"
+
+# Setup some stuff incase things go south and we drop to the shell
+export HOME=/
+export PATH=/sbin:/bin:/usr/sbin:/usr/bin
+umask 022
+
+echo
+echo "Starting ZFS on root boot strapper"
+
+# Avoid having the solaris and zfs modules in ramdisk directly.
+# Means we don't need to update the ramdisk with the kernel modules
+# or load them from boot.cfg so it's less pain for the user.
+#bootdev="$(/sbin/sysctl -n kern.boot_device)"
+modpath="$(/sbin/sysctl -n kern.module.path)"
+modmnt=/mnt
+echo "Copying needed kernel modules from $bootdev:$modpath"
+case "$bootdev" in
+*=*|"/"*)      ;;
+*)             bootdev="/dev/$bootdev";;
+esac
+/sbin/mount -o ro "$bootdev" "$modmnt"
+/sbin/mount -t tmpfs none /stand
+for m in solaris zfs; do
+       p="$modpath/$m"
+       if [ ! -e "$modmnt/$p/$m.kmod" ]; then
+               echo "$modmnt/$p/$m.kmod not found!" >&2
+               continue
+       fi
+       echo "  $m.kmod"
+       /bin/mkdir -p "$p"
+       /bin/cp "$modmnt/$p/$m.kmod" "$p"
+done
+# zpool list will load the needed modules, then we can dispose of the mounts.
+/sbin/zpool list >/dev/null 2>&1
+/sbin/umount /stand
+/sbin/umount "$modmnt"
+echo
+
+echo "Importing $rpool, mounting and pivoting"
+# If we can mount the ZFS root partition to /altroot
+# then chroot to it and start /etc/rc
+if /sbin/zpool import -f -N "$rpool" && \
+   /sbin/mount -t zfs "$rpool/$rroot" /altroot; then
+       # This ensures that mountall mounts all ZFS mounts set to automount.
+       if [ ! -e /altroot/etc/zfs/zpool.cache ]; then
+               echo >/altroot/etc/zfs/zpool.cache
+       fi
+       /sbin/sysctl -w init.root=/altroot
+fi



Home | Main Index | Thread Index | Old Index