From 1bfadf3e6451efbb36d7fd266810cb1e38e8811e Mon Sep 17 00:00:00 2001 From: nl6720 Date: Sat, 24 Oct 2020 15:53:57 +0300 Subject: Support EROFS EROFS, like Squashfs, is a read-only file system. It can be used to store airootfs in an image file. Its advantage is the support for POSIX ACLs. EROFS downside is that currently it only supports LZ4 compression (LZMA support is not yet fully implemented). A difference from Squashfs is that, EROFS stores change time (ctime) not modification time (mtime). The reverse is true for Squashfs. Implements https://gitlab.archlinux.org/archlinux/archiso/-/issues/59 --- hooks/archiso | 45 ++++++++++++++++++++++++++++++++++++++++----- hooks/archiso_pxe_http | 10 ++++++++-- 2 files changed, 48 insertions(+), 7 deletions(-) (limited to 'hooks') diff --git a/hooks/archiso b/hooks/archiso index bf98332..1b848ce 100644 --- a/hooks/archiso +++ b/hooks/archiso @@ -81,12 +81,36 @@ _mnt_sfs() { _mnt_dev "${sfs_dev}" "${mnt}" "-r" "defaults" } +# args: /path/to/image_file, mountpoint +_mnt_erofs() { + local img="${1}" + local mnt="${2}" + local img_fullname="${img##*/}" + local erofs_dev + + # shellcheck disable=SC2154 + # defined via initcpio's parse_cmdline() + if [ "${copytoram}" = "y" ]; then + msg -n ":: Copying EROFS image to RAM..." + if ! cp -- "${img}" "/run/archiso/copytoram/${img_fullname}" ; then + echo "ERROR: while copy '${img}' to '/run/archiso/copytoram/${img_fullname}'" + launch_interactive_shell + fi + img="/run/archiso/copytoram/${img_fullname}" + msg "done." + fi + erofs_dev="$(losetup --find --show --read-only -- "${img}")" + echo "${erofs_dev}" >> /run/archiso/used_block_devices + _mnt_dev "${erofs_dev}" "${mnt}" "-r" "defaults" "erofs" +} + # args: device, mountpoint, flags, opts _mnt_dev() { local dev="${1}" local mnt="${2}" local flg="${3}" local opts="${4}" + local fstype="${5:-auto}" mkdir -p "${mnt}" @@ -99,7 +123,7 @@ _mnt_dev() { launch_interactive_shell done - if mount -o "${opts}" "${flg}" "${dev}" "${mnt}"; then + if mount -t "${fstype}" -o "${opts}" "${flg}" "${dev}" "${mnt}"; then msg ":: Device '${dev}' mounted successfully." else echo "ERROR; Failed to mount '${dev}'" @@ -120,8 +144,9 @@ _verify_checksum() { _verify_signature() { local _status + local sigfile="${1}" cd "/run/archiso/bootmnt/${archisobasedir}/${arch}" || exit 1 - gpg --homedir /gpg --status-fd 1 --verify airootfs.sfs.sig 2>/dev/null | grep -qE '^\[GNUPG:\] GOODSIG' + gpg --homedir /gpg --status-fd 1 --verify "${sigfile}" 2>/dev/null | grep -qE '^\[GNUPG:\] GOODSIG' _status=$? cd -- "${OLDPWD}" || exit 1 return ${_status} @@ -160,6 +185,7 @@ run_hook() { # args: /path/to/newroot archiso_mount_handler() { local newroot="${1}" + local sigfile if ! mountpoint -q "/run/archiso/bootmnt"; then _mnt_dev "${archisodevice}" "/run/archiso/bootmnt" "-r" "defaults" @@ -190,15 +216,20 @@ archiso_mount_handler() { # defined via initcpio's parse_cmdline() if [ "${verify}" = "y" ]; then if [ -f "/run/archiso/bootmnt/${archisobasedir}/${arch}/airootfs.sfs.sig" ]; then + sigfile="airootfs.sfs.sig" + elif [ -f "/run/archiso/bootmnt/${archisobasedir}/${arch}/airootfs.erofs.sig" ]; then + sigfile="airootfs.erofs.sig" + fi + if [ -n "${sigfile}" ]; then msg -n ":: Signature verification requested, please wait..." - if _verify_signature; then + if _verify_signature "${sigfile}"; then msg "done. Signature is OK, continue booting." else echo "ERROR: one or more files are corrupted" launch_interactive_shell fi else - echo "ERROR: verify=y option specified but ${archisobasedir}/${arch}/airootfs.sfs.sig not found" + echo "ERROR: verify=y option specified but GPG signature not found in ${archisobasedir}/${arch}/" launch_interactive_shell fi fi @@ -221,7 +252,11 @@ archiso_mount_handler() { mkdir -p "/run/archiso/cowspace/${cow_directory}" chmod 0700 "/run/archiso/cowspace/${cow_directory}" - _mnt_sfs "/run/archiso/bootmnt/${archisobasedir}/${arch}/airootfs.sfs" "/run/archiso/airootfs" + if [ -f "/run/archiso/bootmnt/${archisobasedir}/${arch}/airootfs.sfs" ]; then + _mnt_sfs "/run/archiso/bootmnt/${archisobasedir}/${arch}/airootfs.sfs" "/run/archiso/airootfs" + elif [ -f "/run/archiso/bootmnt/${archisobasedir}/${arch}/airootfs.erofs" ]; then + _mnt_erofs "/run/archiso/bootmnt/${archisobasedir}/${arch}/airootfs.erofs" "/run/archiso/airootfs" + fi if [ -f "/run/archiso/airootfs/airootfs.img" ]; then _mnt_dmsnapshot "/run/archiso/airootfs/airootfs.img" "${newroot}" "/" else diff --git a/hooks/archiso_pxe_http b/hooks/archiso_pxe_http index efae923..43b8b4b 100644 --- a/hooks/archiso_pxe_http +++ b/hooks/archiso_pxe_http @@ -39,6 +39,7 @@ _curl_get() { archiso_pxe_http_mount_handler () { newroot="${1}" + local img_type="sfs" msg ":: Mounting /run/archiso/httpspace (tmpfs) filesystem, size='${archiso_http_spc}'" mkdir -p "/run/archiso/httpspace" @@ -46,7 +47,12 @@ archiso_pxe_http_mount_handler () { # shellcheck disable=SC2154 # defined via initcpio's parse_cmdline() - _curl_get "${archiso_http_srv}${archisobasedir}/${arch}/airootfs.sfs" "/${arch}" + if ! curl -L -f -o /dev/null -s -r 0-0 "${archiso_http_srv}${archisobasedir}/${arch}/airootfs.sfs"; then + if curl -L -f -o /dev/null -s -r 0-0 "${archiso_http_srv}${archisobasedir}/${arch}/airootfs.erofs"; then + img_type="erofs" + fi + fi + _curl_get "${archiso_http_srv}${archisobasedir}/${arch}/airootfs.${img_type}" "/${arch}" # shellcheck disable=SC2154 # defined via initcpio's parse_cmdline() @@ -56,7 +62,7 @@ archiso_pxe_http_mount_handler () { # shellcheck disable=SC2154 # defined via initcpio's parse_cmdline() if [ "${verify}" = "y" ]; then - _curl_get "${archiso_http_srv}${archisobasedir}/${arch}/airootfs.sfs.sig" "/${arch}" + _curl_get "${archiso_http_srv}${archisobasedir}/${arch}/airootfs.${img_type}.sig" "/${arch}" fi mkdir -p "/run/archiso/bootmnt" -- cgit v1.2.3-70-g09d2