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
This commit is contained in:
parent
711ab4cd1e
commit
bc67933af1
@ -49,9 +49,11 @@ The image file is constructed from some of the variables in **profiledef.sh**: `
|
|||||||
|
|
||||||
- `squashfs`: Create a squashfs image directly from the airootfs work directory
|
- `squashfs`: Create a squashfs image directly from the airootfs work directory
|
||||||
- `ext4+squashfs`: Create an ext4 partition, copy the airootfs work directory to it and create a squashfs image from it
|
- `ext4+squashfs`: Create an ext4 partition, copy the airootfs work directory to it and create a squashfs image from it
|
||||||
* `airootfs_image_tool_options`: An array of options to pass to the tool to create the airootfs image. Currently only
|
- `erofs`: Create an EROFS image for the airootfs work directory
|
||||||
`mksquashfs` is supported - see `mksquashfs --help` for all possible options (defaults to `('-comp' 'xz')`).
|
* `airootfs_image_tool_options`: An array of options to pass to the tool to create the airootfs image. `mksquashfs` and
|
||||||
- `file_permissions`: An associative array that lists files and/or directories who need specific ownership or
|
`mkfs.erofs` are supported. See `mksquashfs --help` or `mkfs.erofs --help` for all possible options (defaults to
|
||||||
|
`('-comp' 'xz')` for squashfs).
|
||||||
|
* `file_permissions`: An associative array that lists files and/or directories who need specific ownership or
|
||||||
permissions. The array's keys contain the path and the value is a colon separated list of owner UID, owner GID and
|
permissions. The array's keys contain the path and the value is a colon separated list of owner UID, owner GID and
|
||||||
access mode. E.g. `file_permissions=(["/etc/shadow"]="0:0:400")`.
|
access mode. E.g. `file_permissions=(["/etc/shadow"]="0:0:400")`.
|
||||||
|
|
||||||
|
@ -81,12 +81,36 @@ _mnt_sfs() {
|
|||||||
_mnt_dev "${sfs_dev}" "${mnt}" "-r" "defaults"
|
_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
|
# args: device, mountpoint, flags, opts
|
||||||
_mnt_dev() {
|
_mnt_dev() {
|
||||||
local dev="${1}"
|
local dev="${1}"
|
||||||
local mnt="${2}"
|
local mnt="${2}"
|
||||||
local flg="${3}"
|
local flg="${3}"
|
||||||
local opts="${4}"
|
local opts="${4}"
|
||||||
|
local fstype="${5:-auto}"
|
||||||
|
|
||||||
mkdir -p "${mnt}"
|
mkdir -p "${mnt}"
|
||||||
|
|
||||||
@ -99,7 +123,7 @@ _mnt_dev() {
|
|||||||
launch_interactive_shell
|
launch_interactive_shell
|
||||||
done
|
done
|
||||||
|
|
||||||
if mount -o "${opts}" "${flg}" "${dev}" "${mnt}"; then
|
if mount -t "${fstype}" -o "${opts}" "${flg}" "${dev}" "${mnt}"; then
|
||||||
msg ":: Device '${dev}' mounted successfully."
|
msg ":: Device '${dev}' mounted successfully."
|
||||||
else
|
else
|
||||||
echo "ERROR; Failed to mount '${dev}'"
|
echo "ERROR; Failed to mount '${dev}'"
|
||||||
@ -120,8 +144,9 @@ _verify_checksum() {
|
|||||||
|
|
||||||
_verify_signature() {
|
_verify_signature() {
|
||||||
local _status
|
local _status
|
||||||
|
local sigfile="${1}"
|
||||||
cd "/run/archiso/bootmnt/${archisobasedir}/${arch}" || exit 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=$?
|
_status=$?
|
||||||
cd -- "${OLDPWD}" || exit 1
|
cd -- "${OLDPWD}" || exit 1
|
||||||
return ${_status}
|
return ${_status}
|
||||||
@ -160,6 +185,7 @@ run_hook() {
|
|||||||
# args: /path/to/newroot
|
# args: /path/to/newroot
|
||||||
archiso_mount_handler() {
|
archiso_mount_handler() {
|
||||||
local newroot="${1}"
|
local newroot="${1}"
|
||||||
|
local sigfile
|
||||||
|
|
||||||
if ! mountpoint -q "/run/archiso/bootmnt"; then
|
if ! mountpoint -q "/run/archiso/bootmnt"; then
|
||||||
_mnt_dev "${archisodevice}" "/run/archiso/bootmnt" "-r" "defaults"
|
_mnt_dev "${archisodevice}" "/run/archiso/bootmnt" "-r" "defaults"
|
||||||
@ -190,15 +216,20 @@ archiso_mount_handler() {
|
|||||||
# defined via initcpio's parse_cmdline()
|
# defined via initcpio's parse_cmdline()
|
||||||
if [ "${verify}" = "y" ]; then
|
if [ "${verify}" = "y" ]; then
|
||||||
if [ -f "/run/archiso/bootmnt/${archisobasedir}/${arch}/airootfs.sfs.sig" ]; 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..."
|
msg -n ":: Signature verification requested, please wait..."
|
||||||
if _verify_signature; then
|
if _verify_signature "${sigfile}"; then
|
||||||
msg "done. Signature is OK, continue booting."
|
msg "done. Signature is OK, continue booting."
|
||||||
else
|
else
|
||||||
echo "ERROR: one or more files are corrupted"
|
echo "ERROR: one or more files are corrupted"
|
||||||
launch_interactive_shell
|
launch_interactive_shell
|
||||||
fi
|
fi
|
||||||
else
|
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
|
launch_interactive_shell
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@ -221,7 +252,11 @@ archiso_mount_handler() {
|
|||||||
mkdir -p "/run/archiso/cowspace/${cow_directory}"
|
mkdir -p "/run/archiso/cowspace/${cow_directory}"
|
||||||
chmod 0700 "/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
|
if [ -f "/run/archiso/airootfs/airootfs.img" ]; then
|
||||||
_mnt_dmsnapshot "/run/archiso/airootfs/airootfs.img" "${newroot}" "/"
|
_mnt_dmsnapshot "/run/archiso/airootfs/airootfs.img" "${newroot}" "/"
|
||||||
else
|
else
|
||||||
|
@ -39,6 +39,7 @@ _curl_get() {
|
|||||||
|
|
||||||
archiso_pxe_http_mount_handler () {
|
archiso_pxe_http_mount_handler () {
|
||||||
newroot="${1}"
|
newroot="${1}"
|
||||||
|
local img_type="sfs"
|
||||||
|
|
||||||
msg ":: Mounting /run/archiso/httpspace (tmpfs) filesystem, size='${archiso_http_spc}'"
|
msg ":: Mounting /run/archiso/httpspace (tmpfs) filesystem, size='${archiso_http_spc}'"
|
||||||
mkdir -p "/run/archiso/httpspace"
|
mkdir -p "/run/archiso/httpspace"
|
||||||
@ -46,7 +47,12 @@ archiso_pxe_http_mount_handler () {
|
|||||||
|
|
||||||
# shellcheck disable=SC2154
|
# shellcheck disable=SC2154
|
||||||
# defined via initcpio's parse_cmdline()
|
# 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
|
# shellcheck disable=SC2154
|
||||||
# defined via initcpio's parse_cmdline()
|
# defined via initcpio's parse_cmdline()
|
||||||
@ -56,7 +62,7 @@ archiso_pxe_http_mount_handler () {
|
|||||||
# shellcheck disable=SC2154
|
# shellcheck disable=SC2154
|
||||||
# defined via initcpio's parse_cmdline()
|
# defined via initcpio's parse_cmdline()
|
||||||
if [ "${verify}" = "y" ]; then
|
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
|
fi
|
||||||
|
|
||||||
mkdir -p "/run/archiso/bootmnt"
|
mkdir -p "/run/archiso/bootmnt"
|
||||||
|
@ -200,13 +200,30 @@ _mkairootfs_squashfs() {
|
|||||||
install -d -m 0755 -- "${isofs_dir}/${install_dir}/${arch}"
|
install -d -m 0755 -- "${isofs_dir}/${install_dir}/${arch}"
|
||||||
_msg_info "Creating SquashFS image, this may take some time..."
|
_msg_info "Creating SquashFS image, this may take some time..."
|
||||||
_run_mksquashfs "${airootfs_dir}"
|
_run_mksquashfs "${airootfs_dir}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Makes an EROFS file system from a source directory.
|
||||||
|
_mkairootfs_erofs() {
|
||||||
|
local fsuuid
|
||||||
|
[[ -e "${airootfs_dir}" ]] || _msg_error "The path '${airootfs_dir}' does not exist" 1
|
||||||
|
|
||||||
|
install -d -m 0755 -- "${isofs_dir}/${install_dir}/${arch}"
|
||||||
|
local image_path="${isofs_dir}/${install_dir}/${arch}/airootfs.erofs"
|
||||||
|
# Generate reproducible file system UUID from SOURCE_DATE_EPOCH
|
||||||
|
fsuuid="$(uuidgen --sha1 --namespace 93a870ff-8565-4cf3-a67b-f47299271a96 --name "${SOURCE_DATE_EPOCH}")"
|
||||||
|
_msg_info "Creating EROFS image, this may take some time..."
|
||||||
|
mkfs.erofs -U "${fsuuid}" "${airootfs_image_tool_options[@]}" -- "${image_path}" "${airootfs_dir}"
|
||||||
_msg_info "Done!"
|
_msg_info "Done!"
|
||||||
}
|
}
|
||||||
|
|
||||||
_mkchecksum() {
|
_mkchecksum() {
|
||||||
_msg_info "Creating checksum file for self-test..."
|
_msg_info "Creating checksum file for self-test..."
|
||||||
cd -- "${isofs_dir}/${install_dir}/${arch}"
|
cd -- "${isofs_dir}/${install_dir}/${arch}"
|
||||||
sha512sum airootfs.sfs > airootfs.sha512
|
if [[ -e "${isofs_dir}/${install_dir}/${arch}/airootfs.sfs" ]]; then
|
||||||
|
sha512sum airootfs.sfs > airootfs.sha512
|
||||||
|
elif [[ -e "${isofs_dir}/${install_dir}/${arch}/airootfs.erofs" ]]; then
|
||||||
|
sha512sum airootfs.erofs > airootfs.sha512
|
||||||
|
fi
|
||||||
cd -- "${OLDPWD}"
|
cd -- "${OLDPWD}"
|
||||||
_msg_info "Done!"
|
_msg_info "Done!"
|
||||||
}
|
}
|
||||||
@ -214,7 +231,11 @@ _mkchecksum() {
|
|||||||
_mksignature() {
|
_mksignature() {
|
||||||
_msg_info "Signing SquashFS image..."
|
_msg_info "Signing SquashFS image..."
|
||||||
cd -- "${isofs_dir}/${install_dir}/${arch}"
|
cd -- "${isofs_dir}/${install_dir}/${arch}"
|
||||||
gpg --detach-sign --default-key "${gpg_key}" airootfs.sfs
|
if [[ -e "${isofs_dir}/${install_dir}/${arch}/airootfs.sfs" ]]; then
|
||||||
|
gpg --detach-sign --default-key "${gpg_key}" airootfs.sfs
|
||||||
|
elif [[ -e "${isofs_dir}/${install_dir}/${arch}/airootfs.erofs" ]]; then
|
||||||
|
gpg --detach-sign --default-key "${gpg_key}" airootfs.erofs
|
||||||
|
fi
|
||||||
cd -- "${OLDPWD}"
|
cd -- "${OLDPWD}"
|
||||||
_msg_info "Done!"
|
_msg_info "Done!"
|
||||||
}
|
}
|
||||||
@ -634,6 +655,13 @@ _validate_requirements_airootfs_image_type_ext4+squashfs() {
|
|||||||
_validate_requirements_airootfs_image_type_squashfs
|
_validate_requirements_airootfs_image_type_squashfs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_validate_requirements_airootfs_image_type_erofs() {
|
||||||
|
if ! command -v mkfs.erofs; then
|
||||||
|
(( validation_error=validation_error+1 ))
|
||||||
|
_msg_error "Validating '${airootfs_image_type}': mkfs.erofs is not available on this host. Install 'erofs-utils'!" 0
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# SYSLINUX El Torito
|
# SYSLINUX El Torito
|
||||||
_add_xorrisofs_options_bios.syslinux.eltorito() {
|
_add_xorrisofs_options_bios.syslinux.eltorito() {
|
||||||
xorrisofs_options+=(
|
xorrisofs_options+=(
|
||||||
|
@ -10,6 +10,7 @@ install_dir="arch"
|
|||||||
bootmodes=('bios.syslinux.mbr' 'bios.syslinux.eltorito' 'uefi-x64.systemd-boot.esp' 'uefi-x64.systemd-boot.eltorito')
|
bootmodes=('bios.syslinux.mbr' 'bios.syslinux.eltorito' 'uefi-x64.systemd-boot.esp' 'uefi-x64.systemd-boot.eltorito')
|
||||||
arch="x86_64"
|
arch="x86_64"
|
||||||
pacman_conf="pacman.conf"
|
pacman_conf="pacman.conf"
|
||||||
|
airootfs_image_type="squashfs"
|
||||||
airootfs_image_tool_options=('-comp' 'xz' '-Xbcj' 'x86' '-b' '1M' '-Xdict-size' '1M')
|
airootfs_image_tool_options=('-comp' 'xz' '-Xbcj' 'x86' '-b' '1M' '-Xdict-size' '1M')
|
||||||
file_permissions=(
|
file_permissions=(
|
||||||
["/etc/shadow"]="0:0:400"
|
["/etc/shadow"]="0:0:400"
|
||||||
|
@ -10,6 +10,7 @@ install_dir="arch"
|
|||||||
bootmodes=('bios.syslinux.mbr' 'bios.syslinux.eltorito' 'uefi-x64.systemd-boot.esp' 'uefi-x64.systemd-boot.eltorito')
|
bootmodes=('bios.syslinux.mbr' 'bios.syslinux.eltorito' 'uefi-x64.systemd-boot.esp' 'uefi-x64.systemd-boot.eltorito')
|
||||||
arch="x86_64"
|
arch="x86_64"
|
||||||
pacman_conf="pacman.conf"
|
pacman_conf="pacman.conf"
|
||||||
|
airootfs_image_type="squashfs"
|
||||||
airootfs_image_tool_options=('-comp' 'xz' '-Xbcj' 'x86' '-b' '1M' '-Xdict-size' '1M')
|
airootfs_image_tool_options=('-comp' 'xz' '-Xbcj' 'x86' '-b' '1M' '-Xdict-size' '1M')
|
||||||
file_permissions=(
|
file_permissions=(
|
||||||
["/etc/shadow"]="0:0:400"
|
["/etc/shadow"]="0:0:400"
|
||||||
|
Loading…
Reference in New Issue
Block a user