# ZFS boot stub for initramfs-tools. # # In the initramfs environment, the /init script sources this stub to # override the default functions in the /scripts/local script. # # Enable this by passing boot=zfs on the kernel command line. # pre_mountroot() { [ "$quiet" != "y" ] && log_begin_msg "Running /scripts/local-top" run_scripts /scripts/local-top [ "$quiet" != "y" ] && log_end_msg if [ -r '/etc/default/zfs' ] then . '/etc/default/zfs' if [ "$ZFS_INITRD_PRE_MOUNTROOT_SLEEP" -gt '0' ] then [ "$quiet" != "y" ] && log_begin_msg "Sleeping for $ZFS_INITRD_PRE_MOUNTROOT_SLEEP seconds..." sleep "$ZFS_INITRD_PRE_MOUNTROOT_SLEEP" [ "$quiet" != "y" ] && log_end_msg fi fi } # Duplicates the functionality found under try_failure_hooks in functions # but invoking that would be inappropriate here. disable_plymouth() { if [ -x /bin/plymouth ] && /bin/plymouth --ping then /bin/plymouth hide-splash >/dev/null 2>&1 fi } mountroot() { pre_mountroot [ "$quiet" != "y" ] && log_begin_msg "Running /scripts/local-premount" run_scripts /scripts/local-premount [ "$quiet" != "y" ] && log_end_msg # Wait for all of the /dev/{hd,sd}[a-z] device nodes to appear. wait_for_udev # Load the module now to get consistent automatic pool import behavior. modprobe zfs # Check the kernel command line for overrides. ZFS_RPOOL="${rpool#rpool=}" ZFS_BOOTFS="${bootfs#bootfs=}" if [ -z "$ZFS_RPOOL" ] then # Check for the `-B zfs-bootfs=%s/%u,...` kind of parameter. # # The ${zfs-bootfs} variable is set at the kernel commmand # line, usually by GRUB, but it cannot be referenced here # directly because bourne variable names cannot contain a # hyphen. # # Reassign the variable by dumping the environment and # stripping the zfs-bootfs= prefix. Let the shell handle # quoting through the eval command. eval ZFS_RPOOL=$(set | sed -n -e 's,^zfs-bootfs=,,p') # Only the pool name is relevant because the ZFS filesystem on # Linux is extrinsic and the userland cannot resolve a ZFS # object number. # # Strip everything after the first slash character. ZFS_RPOOL=$(echo "$ZFS_RPOOL" | sed -e 's,/.*,,') fi # Use "rpool" as the default, like on most Solaris systems. [ -z "$ZFS_RPOOL" ] && ZFS_RPOOL='rpool' # @FIXME: Forcing the import should not be necessary. # # Consider inhibiting automatic zpool imports in the initramfs # environment and doing a full import in the regular system instead. [ "$quiet" != "y" ] && log_begin_msg "Importing ZFS root pool $ZFS_RPOOL" if [ -f /etc/zfs/zpool.cache ] then ZFS_STDERR=$(zpool list "$ZFS_RPOOL" 1>/dev/null 2>&1 \ || zpool import -f -N "$ZFS_RPOOL" 2>&1) ZFS_ERROR=$? else ZFS_STDERR=$(zpool import -f -N "$ZFS_RPOOL" 2>&1) ZFS_ERROR=$? fi [ "$quiet" != "y" ] && log_end_msg if [ "$ZFS_ERROR" -ne 0 ] then disable_plymouth echo "Command: zpool import -f -N $ZFS_RPOOL" echo "Message: $ZFS_STDERR" echo "Error: $ZFS_ERROR" echo "" echo "Manually import the root pool at the command prompt and then exit." echo "Hint: Try: zpool import -f -R / -N $ZFS_RPOOL" # /bin/sh fi if [ -z "$ZFS_BOOTFS" ] then [ "$quiet" != "y" ] && log_begin_msg "Getting ZFS bootfs property" ZFS_BOOTFS=$(zpool list -H -o bootfs "$ZFS_RPOOL") ZFS_ERROR=$? [ "$quiet" != "y" ] && log_end_msg fi if [ -z "$ZFS_BOOTFS" ] then disable_plymouth echo "Command: zpool list -H -o bootfs $ZFS_RPOOL" echo "Error: $ZFS_ERROR, unable to get the bootfs property." echo "" echo "Manually mount the root filesystem on $rootmnt and then exit." echo "Hint: Try: mount -t zfs -o zfsutil $ZFS_RPOOL/ROOT/system $rootmnt" /bin/sh fi # Force the mountpoint to the only correct value for a root filesystem. [ "$quiet" != "y" ] && log_begin_msg "Setting mountpoint=/ on ZFS filesystem $ZFS_BOOTFS" ZFS_STDERR=$(zfs set mountpoint=/ "$ZFS_BOOTFS" 2>&1) [ "$quiet" != "y" ] && log_end_msg # Ideally, the root filesystem would be mounted like this: # # zpool import -R "$rootmnt" -N "$ZFS_RPOOL" # zfs mount -o mountpoint=/ "$ZFS_BOOTFS" # # but the MOUNTPOINT prefix is preserved on descendent filesystem after # the pivot into the regular root, which later breaks things like # `zfs mount -a` and the /etc/mtab refresh. [ "$quiet" != "y" ] && log_begin_msg "Mounting ZFS filesystem $ZFS_BOOTFS" ZFS_STDERR=$(mount -t zfs -o zfsutil "$ZFS_BOOTFS" "$rootmnt" 2>&1) ZFS_ERROR=$? [ "$quiet" != "y" ] && log_end_msg if [ "$ZFS_ERROR" -ne 0 ] then disable_plymouth echo "" echo "Command: mount -t zfs -o zfsutil $ZFS_BOOTFS $rootmnt" echo "Message: $ZFS_STDERR" echo "Error: $ZFS_ERROR" echo "" echo "Manually mount the root filesystem on $rootmnt and then exit." /bin/sh fi [ "$quiet" != "y" ] && log_begin_msg "Running /scripts/local-bottom" run_scripts /scripts/local-bottom [ "$quiet" != "y" ] && log_end_msg }