Skip to content

Commit

Permalink
Add functionality that exists in initramfs to dracut.
Browse files Browse the repository at this point in the history
* Support 'zfs:<rootfs>' import and mounting.
  This was for some reason removed in eda3d4e.
* Support booting from snapshots.
* Support mounting recursive filesystems.
* Support mounting of additional filesystems.
* Support mounting nativly encrypted filesystems.
  • Loading branch information
FransUrbo committed Aug 2, 2015
1 parent dc11abe commit eec3394
Show file tree
Hide file tree
Showing 4 changed files with 162 additions and 81 deletions.
45 changes: 37 additions & 8 deletions contrib/dracut/90zfs/mount-zfs.sh.in
Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,58 @@ esac
udev_trigger

if [ "${root}" = "zfs:AUTO" ] ; then
ZFS_BOOTFS=""
POOLS=$(get_pools)
IFS=";"

for pool in $POOLS
do
[ -z "$pool" ] && continue
ZFS_BOOTFS=""

# No 'else' or return below - if there's more pools, we try
# them. If not, we'll drop through and go to the end
# where we need a reboot because we couldn't find a root fs.
if import_pool "$pool"; then
if find_rootfs "$pool"; then
if mount_fs "${ZFS_BOOTFS}"; then
info "ZFS: Using ${ZFS_BOOTFS} as root."

rootok=1
if zfs_action "Importing pool ${pool}" import_pool "${pool}"
then
if find_rootfs "${pool}"; then
if recursive_mount_filesystems \
"Using '${ZFS_BOOTFS}' as root." \
"${ZFS_BOOTFS}"
then
IFS="$OLD_IFS"

rootok=1
return 0
fi
fi
fi
done
else
# Because of the case at the top, it's either 'zfs:AUTO' or
# 'zfs:<rootfs>'. Import the pool from rootfs and mount it.
root="${root#zfs:}" # Remove leading 'zfs:'
pool="${root%%/*}" # Remove everything after first slash.
ZFS_BOOTFS="${root}" # For zfs-functions.
if zfs_action "Importing pool ${pool}" import_pool "${pool}"; then
info "ZFS: Using ${pool} as root pool."

# Will be overwritten in clone_snap() if we're booting from
# a snapshot.
ZFS_BOOTFS_ORIG="$ZFS_BOOTFS"

# Booting from a snapshot? Updates ZFS_BOOTFS_ORIG and ZFS_BOOTFS...
echo "${root}" | grep -q '@' && setup_snapshot_booting
root="$ZFS_BOOTFS"

if recursive_mount_filesystems "Using '${root}' as root." \
"${root}"
then
rootok=1
return 0
fi
else
warn "ZFS: Can't import '${pool}'."
# Fallthrough
fi
fi

rootok=0
Expand Down
25 changes: 25 additions & 0 deletions contrib/dracut/README.dracut.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,31 @@ parameters passed in from the boot loader:
* `root=...`: If not set, importable pools are searched for a bootfs
attribute. If an explicitly set root is desired, you may use
`root=ZFS:pool/dataset`
* It is also possible to boot from a snapshot (technically, a clone of
the snapshot) using `root=ZFS:pool/dataset@snapshot`.
* If the actual snapshot isn't specified, only the at (@) character,
the user will be asked for a snapshot to boot from.
* With the extra parameter `rollback=(on,yes,1)`, instead of doing a
clone and boot from that, the code will rollback the filesystem up
to the snapshot specified.
* Even though there is no freely availible native encryption for any
opensource ZFS implementation, the hope is that one day have one.
This code supports the native encryption that Solaris have, using
the `zfs key` option.
* Supports both 'native' and 'legacy' filesystems.
* Supports 'recursive filesystems'. That is, if the root file system
is something like `rpool/ROOT/fedora17`, it is possible to have
`rpool/ROOT/fedora17/var`, `rpool/ROOT/fedora17/usr` etc.
It is not important that the 'mountpoint' property is set or correct,
the 'base filesystem' will be removed from the full path of the filesystem.
This means, that with the root fs as `rpool/ROOT/fedora17` and the sub-
filesystem as `rpool/ROOT/fedora17/var`, the result would be `/var`,
where it will be mounted.
* In addition to 'recursive filesystems', it is possible to have other
filesystems mounted by setting the ZFS_INITRD_ADDITIONAL_DATASETS variable
in /etc/sysconfig/zfs. Here, it is imparative that the 'mountpoint'
property is correct for each of these filesystems, since each filesystem
will use this to correctly mount it.

* `zfs_force=0`: If set to 1, the initramfs will run `zpool import -f` when
attempting to import pools if the required pool isn't automatically imported
Expand Down
22 changes: 12 additions & 10 deletions contrib/initramfs/scripts/zfs
Original file line number Diff line number Diff line change
Expand Up @@ -339,16 +339,18 @@ mountroot()
if [ "${ZFS_ERROR}" != 0 ]
then
disable_plymouth
echo ""
echo "Command: ${ZFS_CMD}"
echo "Message: ${ZFS_STDERR}"
echo "Error: ${ZFS_ERROR}"
echo ""
echo "Error: Failed to mount root filesystem '${ZFS_BOOTFS}'."
echo ""
echo "Manually mount the filesystem and exit."
echo "Hint: Try: mount -o zfsutil -t zfs ${ZFS_BOOTFS} $rootmnt"
emergency_shell
if [ "$?" != 999 ]; then
echo ""
echo "Command: ${ZFS_CMD}"
echo "Message: ${ZFS_STDERR}"
echo "Error: ${ZFS_ERROR}"
echo ""
echo "Error: Failed to mount root filesystem '${ZFS_BOOTFS}'."
echo ""
echo "Manually mount the filesystem and exit."
echo "Hint: Try: mount -o zfsutil -t zfs ${ZFS_BOOTFS} $rootmnt"
emergency_shell
fi
fi

# ------------
Expand Down
151 changes: 88 additions & 63 deletions contrib/shell-common/zfs-functions.in
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,6 @@ check_module_loaded()
[ -r "/sys/module/${module}/version" ] && return 0 || return 1
}

# Load specified module.
load_module()
{
module="$1"
Expand Down Expand Up @@ -692,14 +691,18 @@ import_pool()
[ "${quiet}" != "y" ] && zfs_log_failure_msg "${ZFS_ERROR}"

disable_plymouth
echo ""
echo "Command: ${ZFS_CMD} '${pool}'"
echo "Message: ${ZFS_STDERR}"
echo "Error: ${ZFS_ERROR}"
echo ""
echo "Failed to import pool '${pool}'."
echo "Manually import the pool and exit."
emergency_shell
if [ "$?" != 999 ]; then
echo ""
echo "Command: ${ZFS_CMD} '${pool}'"
echo "Message: ${ZFS_STDERR}"
echo "Error: ${ZFS_ERROR}"
echo ""
echo "Failed to import pool '${pool}'."
echo "Manually import the pool and exit."
emergency_shell
else
return 1
fi
fi
fi

Expand Down Expand Up @@ -764,14 +767,18 @@ mount_fs()
[ "${quiet}" != "y" ] && zfs_log_failure_msg "${ZFS_ERROR}"

disable_plymouth
echo ""
echo "Command: ${ZFS_CMD} ${fs} ${rootmnt}/${mountpoint}"
echo "Message: ${ZFS_STDERR}"
echo "Error: ${ZFS_ERROR}"
echo ""
echo "Failed to mount ${fs} on ${rootmnt}/${mountpoint}."
echo "Manually mount the filesystem and exit."
emergency_shell
if [ "$?" != 999 ]; then
echo ""
echo "Command: ${ZFS_CMD} ${fs} ${rootmnt}/${mountpoint}"
echo "Message: ${ZFS_STDERR}"
echo "Error: ${ZFS_ERROR}"
echo ""
echo "Failed to mount ${fs} on ${rootmnt}/${mountpoint}."
echo "Manually mount the filesystem and exit."
emergency_shell
else
return 1
fi
else
return 1
fi
Expand Down Expand Up @@ -807,18 +814,20 @@ decrypt_fs()
[ "${quiet}" != "y" ] && zfs_log_failure_msg "${ZFS_ERROR}"

disable_plymouth
echo ""
echo "Command: ${ZFS_CMD}"
echo "Message: ${ZFS_STDERR}"
echo "Error: ${ZFS_ERROR}"
echo ""
echo "Failed to load ${mod} module."
echo "Please verify that it is availible on the initrd image"
echo "(without it it won't be possible to unlock the filesystem)"
echo "and rerun: ${ZFS_CMD}"
emergency_shell
else
return 1
if [ "$?" != 999 ]; then
echo ""
echo "Command: ${ZFS_CMD}"
echo "Message: ${ZFS_STDERR}"
echo "Error: ${ZFS_ERROR}"
echo ""
echo "Failed to load ${mod} module."
echo "Please verify that it is availible on the initrd image"
echo "(without it it won't be possible to unlock the filesystem)"
echo "and rerun: ${ZFS_CMD}"
emergency_shell
else
return 1
fi
fi
done

Expand All @@ -830,15 +839,19 @@ decrypt_fs()
[ "${quiet}" != "y" ] && zfs_log_failure_msg "${ZFS_ERROR}"

disable_plymouth
echo ""
echo "Command: ${ZFS_CMD}"
echo "Message: ${ZFS_STDERR}"
echo "Error: ${ZFS_ERROR}"
echo ""
echo "Failed to load zfs encryption wrapper key (s)."
echo "Please verify dataset property 'keysource' for datasets"
echo "and rerun: ${ZFS_CMD}"
emergency_shell
if [ "$?" != 999 ]; then
echo ""
echo "Command: ${ZFS_CMD}"
echo "Message: ${ZFS_STDERR}"
echo "Error: ${ZFS_ERROR}"
echo ""
echo "Failed to load zfs encryption wrapper key (s)."
echo "Please verify dataset property 'keysource' for datasets"
echo "and rerun: ${ZFS_CMD}"
emergency_shell
else
return 1
fi
else
return 1
fi
Expand All @@ -861,15 +874,19 @@ destroy_fs()
[ "${quiet}" != "y" ] && zfs_log_failure_msg "${ZFS_ERROR}"

disable_plymouth
echo ""
echo "Command: ${ZFS_CMD}"
echo "Message: ${ZFS_STDERR}"
echo "Error: ${ZFS_ERROR}"
echo ""
echo "Failed to destroy '${fs}'. Please make sure that '${fs}' is not availible."
echo "Hint: Try: zfs destroy -Rfn ${fs}"
echo "If this dryrun looks good, then remove the 'n' from '-Rfn' and try again."
emergency_shell
if [ "$?" != 999 ]; then
echo ""
echo "Command: ${ZFS_CMD}"
echo "Message: ${ZFS_STDERR}"
echo "Error: ${ZFS_ERROR}"
echo ""
echo "Failed to destroy '${fs}'. Please make sure that '${fs}' is not availible."
echo "Hint: Try: zfs destroy -Rfn ${fs}"
echo "If this dryrun looks good, then remove the 'n' from '-Rfn' and try again."
emergency_shell
else
return 1
fi
else
return 1
fi
Expand Down Expand Up @@ -903,15 +920,19 @@ clone_snap()
[ "${quiet}" != "y" ] && zfs_log_failure_msg "${ZFS_ERROR}"

disable_plymouth
echo ""
echo "Command: ${ZFS_CMD}"
echo "Message: ${ZFS_STDERR}"
echo "Error: ${ZFS_ERROR}"
echo ""
echo "Failed to clone snapshot."
echo "Make sure that the any problems are corrected and then make sure"
echo "that the dataset '${destfs}' exists and is bootable."
emergency_shell
if [ "$?" != 999 ]; then
echo ""
echo "Command: ${ZFS_CMD}"
echo "Message: ${ZFS_STDERR}"
echo "Error: ${ZFS_ERROR}"
echo ""
echo "Failed to clone snapshot."
echo "Make sure that the any problems are corrected and then make sure"
echo "that the dataset '${destfs}' exists and is bootable."
emergency_shell
else
return 1
fi
else
return 1
fi
Expand All @@ -933,13 +954,17 @@ rollback_snap()
[ "${quiet}" != "y" ] && zfs_log_failure_msg "${ZFS_ERROR}"

disable_plymouth
echo ""
echo "Command: ${ZFS_CMD}"
echo "Message: ${ZFS_STDERR}"
echo "Error: ${ZFS_ERROR}"
echo ""
echo "Failed to rollback snapshot."
emergency_shell
if [ "$?" != 999 ]; then
echo ""
echo "Command: ${ZFS_CMD}"
echo "Message: ${ZFS_STDERR}"
echo "Error: ${ZFS_ERROR}"
echo ""
echo "Failed to rollback snapshot."
emergency_shell
else
return 1
fi
else
return 1
fi
Expand Down

0 comments on commit eec3394

Please sign in to comment.