#!/bin/bash

build() {
	local applet

	# add parts of base hook:
	# - busybox with applet symlinks
	# - kmod with applet symlinks
	# - blkid
	add_binary /usr/lib/initcpio/busybox /usr/bin/busybox
	for applet in $(/usr/lib/initcpio/busybox --list); do
		# do not add busybox symlinks over potentially real binaries
		# (e.g. setfont added by sd-vconsole)
		[[ -e "$BUILDROOT/usr/bin/$applet" ]] || \
			add_symlink "/usr/bin/$applet" busybox
	done
	add_binary kmod
	for applet in {dep,ins,rm,ls}mod mod{probe,info}; do
		# these are the "real" things, no check is needed
		add_symlink "/usr/bin/$applet" kmod
	done
	add_binary blkid

	# Kernel modules
	map add_module \
		zfs \
		spl \

	# udev rules
	map add_file \
		/usr/lib/udev/rules.d/60-zvol.rules \
		/usr/lib/udev/rules.d/69-vdev.rules \
		/usr/lib/udev/rules.d/90-zfs.rules \

	# systemd units
	map add_systemd_unit \
		systemd-udev-settle.service \

	# ZFS binaries
	map add_binary \
		zpool \
		zfs \
		mount.zfs \
		/usr/lib/udev/vdev_id \
		/usr/lib/udev/zvol_id \

	# Generator and support scripts
	add_file /usr/lib/zfs/initcpio/zfs-root-generator /usr/lib/systemd/system-generators/
	map add_file \
		/usr/lib/zfs/initcpio/zfs-functions \
		/usr/lib/zfs/initcpio/zfs-parse-* \
		/usr/lib/zfs/initcpio/zfs-prepare-* \

	# support binaries (tools) not part of busybox
	# XXX: get rid of xargs (ask mkinitcpio-busybox to build xargs)
	# XXX: get rid of stdbuf (debugging hack)
	map add_binary \
		systemd-escape \
		xargs \
		stdbuf \
		/usr/lib/coreutils/libstdbuf.so \

	# debugging scripts
	add_file /usr/lib/zfs/initcpio/zfs-listp /usr/bin/

	# ZFS-relevant configuration files
	local copied_files=(
		# /etc/zfs/zpool.cache
		# /etc/modprobe.d/{spl,zfs}.conf
		/etc/hostid
	)
	for f in "${copied_files[@]}"; do
		if [[ -e "$f" ]]; then
			add_file "$f"
		fi
	done

	# Synthesize hostid if necessary
	if [[ ! -e /etc/hostid ]]; then
		zgenhostid -o "${BUILDROOT}/etc/hostid" "$(hostid)"
	fi
}

help() {
	cat <<"EOF"
This hook implements ZFS rootfs support for systemd-based initramfs.

This hook is implemented using shell scripts, thus it still requires busybox
(and several standalone coreutils programs). If the `base` hook is not used,
these binaries will be added to the initcpio.

To use this hook, a special `root=` or `zfsroot=` kernel cmdline parameter
must be specified. Three modes of operation are supported:

  1. `root=zfs`, which imports all pools in initrd, searches for the first pool
      with the `bootfs` property set, and then mounts that dataset as root;
  2. `root=zfs:poolname`, which imports the specified pool and then mounts
     the pool's bootfs as root;
  3. `root=zfs:poolname/dataset`, which imports the specified pool and then
     mounts the specified dataset as root (ignoring bootfs property).

Additionally, rudimentary dual-boot support from the same pool is provided.
To mark all datasets that belong to the same OS, set a `dev.sd-zfs:machine-id`
property to the same value on all such datasets. Datasets with other values
of this property will not be mounted. Datasets with no such property will be
considered "shared" and will not receive any special handling.

When dual-boot support is in use, a special `zfsalt=` kernel cmdline parameter
may also be specified. When set to `/path`, datasets that belong to other OSes
will be mounted under `/path/<dev.sd-zfs:machine-id>` instead of being ignored.

WARNING: the dual-boot support is implemented by statefully adjusting the
         `canmount` and `mountpoint` properties on the participating datasets,
         and therefore must be considered a hack.
EOF
}

# vim: ft=bash ts=8 noet:
