Skip to content

Commit

Permalink
Merge pull request commontorizon#33 from rborn-tx/TOR-3377
Browse files Browse the repository at this point in the history
Integrate ostree version supporting composefs
  • Loading branch information
jsrc27 authored Mar 4, 2024
2 parents 9e224f6 + cf45b0b commit 1c82b87
Show file tree
Hide file tree
Showing 38 changed files with 874 additions and 665 deletions.
35 changes: 2 additions & 33 deletions classes/image_type_torizon.bbclass
Original file line number Diff line number Diff line change
Expand Up @@ -133,39 +133,8 @@ generate_diff_file () {
fi
}

EXTRA_DO_IMAGE_OSTREECOMMIT_POSTFUNCS = " "
EXTRA_DO_IMAGE_OSTREECOMMIT_POSTFUNCS:torizon-signed = "composefs_image_gen"
EXTRA_DO_IMAGE_OSTREECOMMIT_DEPENDS = " "
EXTRA_DO_IMAGE_OSTREECOMMIT_DEPENDS:torizon-signed = "composefs-tools-native:do_populate_sysroot fsverity-utils-native:do_populate_sysroot"
do_image_ostreecommit[postfuncs] += "${EXTRA_DO_IMAGE_OSTREECOMMIT_POSTFUNCS}"
do_image_ostreecommit[depends] += "${EXTRA_DO_IMAGE_OSTREECOMMIT_DEPENDS}"
composefs_image_gen() {
OSTREE_COMMIT=$(cat ${WORKDIR}/ostree_manifest)
OSTREE_CFS_REPO=${WORKDIR}/composefs-ostree
CFS_JSON_FILE=${WORKDIR}/composefs-${OSTREE_COMMIT}.json
CFS_IMG_FILE=${WORKDIR}/composefs-${OSTREE_COMMIT}.img

rm -rf ${WORKDIR}/composefs-*
rm -rf ${OSTREE_CFS_REPO} && mkdir -p ${OSTREE_CFS_REPO}

ostree admin --sysroot=${OSTREE_CFS_REPO} init-fs --modern ${OSTREE_CFS_REPO}
ostree --repo=${OSTREE_CFS_REPO}/ostree/repo pull-local --remote=${OSTREE_OSNAME} ${OSTREE_REPO} ${OSTREE_COMMIT}

ostree-convert-commit.py ${OSTREE_CFS_REPO}/ostree/repo ${OSTREE_COMMIT} > ${CFS_JSON_FILE}
writer-json --out=${CFS_IMG_FILE} ${CFS_JSON_FILE}

fsverity digest --compact ${CFS_IMG_FILE} > ${WORKDIR}/composefs_digest
}
CONVERSION_CMD:tar:prepend:torizon-signed = "cp ${WORKDIR}/composefs-*.img ${OTA_SYSROOT}/ostree/deploy/torizon/deploy/ ; "

EXTRA_DO_IMAGE_OTA_PREFUNCS = " "
EXTRA_DO_IMAGE_OTA_PREFUNCS:torizon-signed = "composefs_image_digest_set"
do_image_ota[prefuncs] += "${EXTRA_DO_IMAGE_OTA_PREFUNCS}"
python composefs_image_digest_set() {
with open(d.getVar('WORKDIR') + "/composefs_digest") as f:
digest = f.read()
d.setVar('OSTREE_KERNEL_ARGS_EXTRA', "cfs_digest=" + digest.rstrip('\n'))
}
# Enable composefs on the generated ostree repo (part of the Tezi image).
OSTREE_OTA_REPO_CONFIG:append:cfs-support = " ex-integrity.composefs:true"

IMAGE_DATETIME_FILES ??= " \
${sysconfdir}/issue \
Expand Down
18 changes: 15 additions & 3 deletions classes/torizon-signed.bbclass
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
# TorizonCore configuration for signed images

# inherit class to sign BSP related images
# Inherit class to sign BSP related images (bootloader, kernel FIT image).
inherit tdx-signed

# globally enable signing of operating system images
DISTROOVERRIDES:append = ":torizon-signed"
# Enable protection features related to the root filesystem; this is done by
# means of two overrides, namely:
#
# - cfs-support: Enable composefs support; when set, the ostree deployments will
# contain a composefs image (by default) and the system will usually boot from
# that image; however, the presence of the composefs image will not be
# enforced at runtime. Unless that presence is enforced by other overrides,
# the system will be capable of booting from a legacy ostree deployment (based
# on hardlinks).
#
# - cfs-signed: TBD (not yet implemented)
#
# TODO: Get rid of remaining uses of override "torizon-signed".
DISTROOVERRIDES:append = ":cfs-support"
8 changes: 7 additions & 1 deletion classes/torizon.bbclass
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@
# This boot arguments are supplied to OSTree deploy command. To
# change kernel boot arguments in a deployed OSTree use:
# ostree admin deploy --karg-none --karg="newargs" ...
OSTREE_KERNEL_ARGS = "quiet logo.nologo vt.global_cursor_default=0 plymouth.ignore-serial-consoles splash fbcon=map:3 ${OSTREE_KERNEL_ARGS_EXTRA}"
OSTREE_KERNEL_ARGS = "quiet logo.nologo vt.global_cursor_default=0 plymouth.ignore-serial-consoles splash fbcon=map:3"

# When composefs support is enabled the root mount will usually be an overlay
# and the systemd-gpt-auto-generator generator will complain because it cannot
# determine the block device associated with that mount; disable the generator
# to avoid warning messages during boot.
OSTREE_KERNEL_ARGS:append:cfs-support = " systemd.gpt_auto=0"

OSTREE_KERNEL = "${@'${KERNEL_IMAGETYPE}-${INITRAMFS_IMAGE}-${MACHINE}-${MACHINE}' if d.getVar('KERNEL_IMAGETYPE') == 'fitImage' else '${KERNEL_IMAGETYPE}'}"
OSTREE_DEPLOY_DEVICETREE = "${@'0' if d.getVar('KERNEL_IMAGETYPE') == 'fitImage' else '1'}"
Expand Down
7 changes: 7 additions & 0 deletions conf/distro/include/torizon.inc
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,10 @@ CURLVERSION ?= "8.6.0"

PREFERRED_VERSION_curl ?= "${CURLVERSION}"
PREFERRED_VERSION_libcurl ?= "${CURLVERSION}"

# Choose a newer version of ostree only if override "cfs-support" is set which
# would be the case on a secure-boot image. Otherwise, the older battle-tested
# version is selected.
OSTREEVERSION ?= "2021.6"
OSTREEVERSION:cfs-support ?= "2024.1"
PREFERRED_VERSION_ostree ?= "${OSTREEVERSION}"
6 changes: 6 additions & 0 deletions recipes-core/base-files/base-files_%.bbappend
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,9 @@ do_install_basefilesissue () {
printf "%s \\\n \\\l\n\n" "${DISTRO_VERSION}" >> ${D}${sysconfdir}/issue
printf "%s %%h\n\n" "${DISTRO_VERSION}" >> ${D}${sysconfdir}/issue.net
}

do_install:append:cfs-support () {
# Get rid of the /dev/root entry in fstab to avoid errors from
# systemd-remount-fs.
sed -i -e '\#^ */dev/root#d' ${D}${sysconfdir}/fstab
}
2 changes: 1 addition & 1 deletion recipes-core/images/initramfs-ostree-torizon-image.bb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ PACKAGE_INSTALL = "initramfs-framework-base initramfs-module-udev \
initramfs-module-plymouth ${VIRTUAL-RUNTIME_base-utils} base-passwd \
initramfs-module-kmod"

PACKAGE_INSTALL:append:torizon-signed = "\
PACKAGE_INSTALL:append:cfs-support = "\
initramfs-module-composefs \
"

Expand Down
3 changes: 2 additions & 1 deletion recipes-core/initramfs-framework/files/80-composefs.conf
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
composefs
overlay
erofs
56 changes: 7 additions & 49 deletions recipes-core/initramfs-framework/files/composefs
Original file line number Diff line number Diff line change
Expand Up @@ -13,54 +13,12 @@ composefs_error() {
composefs_run() {
info "Running composefs script..."

if [ -z "$ROOTFS_DIR" ]; then
composefs_error "Cannot find rootfs location!"
if [ -d "$ROOTFS_DIR" ]; then
# When built with composefs support ostree-prepare-root will
# look for objects under /sysroot which is actually the rootfs
# directory in the ramdisk.
ln -sf "$ROOTFS_DIR" /sysroot
else
debug "No rootfs has been set"
fi

if [ -z $ostree ]; then
composefs_error "ostree variable is not set!"
fi

if [ -z $cfs_digest ]; then
composefs_error "cfs_digest variable is not set!"
fi

local OSTREE_COMMIT=$(readlink -f $ROOTFS_DIR/$ostree | cut -d "/" -f 8 | cut -d "." -f 1)
if [ -z $OSTREE_COMMIT ]; then
composefs_error "Could not find ostree commit!"
fi

local CFS_IMAGE=$ROOTFS_DIR/ostree/deploy/torizon/deploy/composefs-$OSTREE_COMMIT.img
local OSTREE_OBJECTS_DIR=$ROOTFS_DIR/sysroot/ostree/repo/objects

# enable fsverity
#TODO: we should do this at image generation or during image installation (via Easy Installer)
if ! fsverity measure $CFS_IMAGE 2>/dev/null; then
info "Enabling fsverity..."
for f in $(ls -1 $OSTREE_OBJECTS_DIR/*/* 2>/dev/null); do
fsverity enable $f 2>/dev/null
done
fsverity enable $CFS_IMAGE
fi

local CFS_MOUNT_DIR=$ROOTFS_DIR/sysroot/cfs
mkdir -p $CFS_MOUNT_DIR

info "Mounting composefs image..."
if ! mount -t composefs -o basedir=$OSTREE_OBJECTS_DIR,digest=$cfs_digest,verity_check=2 \
$CFS_IMAGE $CFS_MOUNT_DIR; then
composefs_error "Could not mount composefs image!"
fi

info "Bind mounting /usr..."
umount $ROOTFS_DIR/usr
if ! mount --bind $CFS_MOUNT_DIR/usr $ROOTFS_DIR/usr; then
composefs_error "Could not bind mount /usr!"
fi

# this seems to be necessary for the files to have root:root ownership after switch_root
# TODO: it requires some investigation
find $ROOTFS_DIR/usr/ >/dev/null 2>&1

return 0
}
39 changes: 33 additions & 6 deletions recipes-core/initramfs-framework/initramfs-framework_1.0.bbappend
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ SRC_URI += "\
file://0002-only-scan-for-block-devices.patch \
"

SRC_URI:append:torizon-signed = "\
SRC_URI:append:cfs-support = "\
file://composefs \
file://80-composefs.conf \
"
Expand All @@ -19,7 +19,7 @@ PACKAGES:append = " \
initramfs-module-kmod \
"

PACKAGES:append:torizon-signed = "\
PACKAGES:append:cfs-support = "\
initramfs-module-composefs \
"

Expand All @@ -32,8 +32,11 @@ RDEPENDS:initramfs-module-ostree = "${PN}-base ostree-switchroot"
FILES:initramfs-module-ostree = "/init.d/95-ostree"

SUMMARY:initramfs-module-composefs = "initramfs support for booting composefs images"
RDEPENDS:initramfs-module-composefs = "${PN}-base kernel-module-composefs fsverity-utils util-linux-mount"
FILES:initramfs-module-composefs = "/init.d/98-composefs"
RDEPENDS:initramfs-module-composefs = "${PN}-base kernel-module-erofs kernel-module-overlay"
FILES:initramfs-module-composefs = "\
/init.d/94-composefs \
${nonarch_libdir}/ostree/prepare-root.conf \
"

SUMMARY:initramfs-module-kmod = "initramfs support for loading kernel modules"
RDEPENDS:initramfs-module-kmod = "${PN}-base"
Expand All @@ -48,10 +51,34 @@ do_install:append() {
install -m 0755 ${WORKDIR}/kmod ${D}/init.d/01-kmod
}

do_install:append:torizon-signed() {
install -m 0755 ${WORKDIR}/composefs ${D}/init.d/98-composefs
# Configuration that goes into prepare-root.conf (see ostree-prepare-root manual):
# - PREP_ROOT_ETC_TRANSIENT: whether /etc is transient ("true" or "false")
# - PREP_ROOT_CFS_ENABLED: enabling of composefs ("yes", "no", "maybe" or "signed")
#
# TODO: Set PREP_ROOT_ETC_TRANSIENT to true; at the time of writing this wasn't
# working correctly: /etc does become transient but "ostree admin status" fails
# to detect the current deployment (this may have been solved on newer versions
# of ostree).
PREP_ROOT_ETC_TRANSIENT ?= "false"
PREP_ROOT_CFS_ENABLED ?= "maybe"
PREP_ROOT_CFS_ENABLED:cfs-signed ?= "signed"

do_install:append:cfs-support() {
# Bundled into initramfs-module-kmod package:
install -d ${D}/etc/modules-load.d/
install -m 0755 ${WORKDIR}/80-composefs.conf ${D}/etc/modules-load.d/80-composefs.conf

# Bundled into initramfs-module-composefs package:
install -m 0755 ${WORKDIR}/composefs ${D}/init.d/94-composefs
install -d ${D}${nonarch_libdir}/ostree/
install -m 0644 /dev/null ${D}${nonarch_libdir}/ostree/prepare-root.conf
cat >${D}${nonarch_libdir}/ostree/prepare-root.conf <<EOF
[etc]
transient = ${PREP_ROOT_ETC_TRANSIENT}

[composefs]
enabled = ${PREP_ROOT_CFS_ENABLED}
EOF
}

# Adding modules so plymouth can show the splash screen during boot
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
From 53a086ba294215508acba550237ab83f7d136c3e Mon Sep 17 00:00:00 2001
From: Rogerio Guerra Borin <[email protected]>
Date: Wed, 7 Feb 2024 00:19:45 -0300
Subject: [PATCH] Expose MOUNT_ATTR_IDMAP detection result to C code

This is to allow compiling composefs on machines having somewhat old
Linux kernel headers.

Signed-off-by: Rogerio Guerra Borin <[email protected]>
---
configure.ac | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/configure.ac b/configure.ac
index 4800477a..b6eb6c3f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -292,7 +292,8 @@ AC_COMPILE_IFELSE(
],[int foo = MOUNT_ATTR_IDMAP;]
)],
[AC_MSG_RESULT(yes)
- have_mount_attr_idmap=yes],
+ AC_DEFINE([HAVE_MOUNT_ATTR_IDMAP], 1, [Define if MOUNT_ATTR_IDMAP is available in linux/mount.h])
+ have_mount_attr_idmap=yes],
[AC_MSG_RESULT(no)])
dnl These are needed by libcomposefs to use the new mount API optionally
AC_MSG_CHECKING([for new mount API (fsconfig)])
--
2.25.1

Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
From c5241e94030f774df5f410e07c4de894d41e64e2 Mon Sep 17 00:00:00 2001
From: Rogerio Guerra Borin <[email protected]>
Date: Tue, 6 Feb 2024 23:14:20 -0300
Subject: [PATCH 1/2] mount: Allow building when macro MOUNT_ATTR_IDMAP is not
available

This is to allow building the software on machines not having the
MOUNT_ATTR_IDMAP macro in header "linux/mount.h". When that macro is not
available, the dependency on struct mount_attr is also eliminated (which
is good since both the macro and the struct were added to the kernel
uapi virtually at the same time).

With the changes in this commit, errors would be thrown at runtime when
mounting the erofs image, but only if the idmap feature is used; this
resembles the behavior when the "new mount API" is not detected.

Upstream-Status: Accepted [https://github.com/containers/composefs/pull/253]

Signed-off-by: Rogerio Guerra Borin <[email protected]>
---
configure.ac | 11 +++++++++++
libcomposefs/lcfs-mount.c | 6 ++++++
2 files changed, 17 insertions(+)

diff --git a/composefs/configure.ac b/composefs/configure.ac
index b8ff154..1aa49e4 100644
--- a/composefs/configure.ac
+++ b/composefs/configure.ac
@@ -16,6 +16,17 @@ m4_ifdef([PKG_INSTALLDIR], [PKG_INSTALLDIR], AC_SUBST([pkgconfigdir], ${libdir}/
PKGCONFIG_REQUIRES=
PKGCONFIG_REQUIRES_PRIVATELY=

+AC_MSG_CHECKING([for MOUNT_ATTR_IDMAP])
+AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([
+ #include <sys/mount.h>
+ #include <linux/mount.h>
+ ],[int foo = MOUNT_ATTR_IDMAP;]
+ )],
+ [AC_MSG_RESULT(yes)
+ AC_DEFINE([HAVE_MOUNT_ATTR_IDMAP], 1, [Define if MOUNT_ATTR_IDMAP is available in linux/mount.h])],
+ [AC_MSG_RESULT(no)])
+
AC_MSG_CHECKING([for new mount API (fsconfig)])
AC_COMPILE_IFELSE(
[AC_LANG_SOURCE([[
diff --git a/composefs/libcomposefs/lcfs-mount.c b/composefs/libcomposefs/lcfs-mount.c
index 0a4b08f..5285833 100644
--- a/composefs/libcomposefs/lcfs-mount.c
+++ b/composefs/libcomposefs/lcfs-mount.c
@@ -108,6 +108,7 @@ static int syscall_move_mount(int from_dfd, const char *from_pathname, int to_df
#endif
}

+#ifdef HAVE_MOUNT_ATTR_IDMAP
static int syscall_mount_setattr(int dfd, const char *path, unsigned int flags,
struct mount_attr *attr, size_t usize)
{
@@ -122,6 +123,7 @@ static int syscall_mount_setattr(int dfd, const char *path, unsigned int flags,
return -1;
#endif
}
+#endif

#define MAX_DIGEST_SIZE 64

@@ -381,6 +383,7 @@ static int lcfs_mount_erofs(const char *source, const char *target,
return -errno;

if (use_idmap) {
+#ifdef HAVE_MOUNT_ATTR_IDMAP
struct mount_attr attr = {
.attr_set = MOUNT_ATTR_IDMAP,
.userns_fd = state->options->idmap_fd,
@@ -390,6 +393,9 @@ static int lcfs_mount_erofs(const char *source, const char *target,
sizeof(struct mount_attr));
if (res < 0)
return -errno;
+#else
+ return -ENOTSUP;
+#endif
}

res = syscall_move_mount(fd_mnt, "", AT_FDCWD, target,
--
2.25.1

Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
From 9919910eff1fbf40260b307ace287b3192436629 Mon Sep 17 00:00:00 2001
From: Mike Sul <[email protected]>
Date: Sat, 3 Jul 2021 20:37:08 -0300
Subject: [PATCH] ostree-fetcher-curl: set a timeout for an overall request
processing

Signed-off-by: Mike Sul <[email protected]>
Signed-off-by: Ricardo Salveti <[email protected]>
---
src/libostree/ostree-fetcher-curl.c | 9 +++++++++
1 file changed, 9 insertions(+)

diff --git a/src/libostree/ostree-fetcher-curl.c b/src/libostree/ostree-fetcher-curl.c
index e9b9672b..dd3bd8a5 100644
--- a/src/libostree/ostree-fetcher-curl.c
+++ b/src/libostree/ostree-fetcher-curl.c
@@ -961,6 +961,15 @@ initiate_next_curl_request (FetcherRequest *req, GTask *task)
rc = curl_easy_setopt (req->easy, CURLOPT_PROGRESSDATA, task);
g_assert_cmpint (rc, ==, CURLM_OK);

+ /* set a request timeout, make sure it's not 0, otherwise an overall ostree pull session might hang */
+ long curl_timeout = 0L;
+ const char* curl_timeout_str = g_getenv ("OSTREE_CURL_TIMEOUT");
+ if (curl_timeout_str != NULL)
+ curl_timeout = atoi(curl_timeout_str);
+ if (curl_timeout == 0)
+ curl_timeout = 780L;
+ curl_easy_setopt (req->easy, CURLOPT_TIMEOUT, curl_timeout);
+
CURLMcode multi_rc = curl_multi_add_handle (self->multi, req->easy);
g_assert (multi_rc == CURLM_OK);
}
--
2.25.1

Loading

0 comments on commit 1c82b87

Please sign in to comment.