Merge branch 'kai/shim-systemd'

This commit is contained in:
Arzhan Kinzhalin
2017-10-18 20:16:17 +00:00
25 changed files with 1273 additions and 362 deletions
+2 -1
View File
@@ -31,6 +31,8 @@ addons:
- lcov
- llvm-3.8
- valgrind
- gnu-efi
- libefivar-dev
before_install:
@@ -42,7 +44,6 @@ script:
- ./configure --enable-coverage && make && make check && make distcheck && make check-valgrind
- clang-format-3.8 -i $(find . -name '*.[ch]') && git diff --exit-code
after_success:
- cd ${TRAVIS_BUILD_DIR}
- lcov --compat-libtool --directory . --capture --output-file coverage.info
+285 -256
View File
@@ -2,73 +2,78 @@ ACLOCAL_AMFLAGS = -I m4
EXTRA_DIST = ${top_srcdir}/README.md \
${top_srcdir}/LICENSE.LGPL2.1 \
${top_srcdir}/HACKING \
${top_srcdir}/findstatic.pl \
${top_srcdir}/tests/data/blobfile \
${top_srcdir}/tests/data/match \
${top_srcdir}/tests/data/match1 \
${top_srcdir}/tests/data/nomatch1 \
${top_srcdir}/tests/data/nomatch2 \
${top_srcdir}/tests/data/clear.os-release \
${top_srcdir}/tests/data/solus.os-release \
${top_srcdir}/tests/data/cmdline/comments \
${top_srcdir}/tests/data/cmdline/mangledmess \
${top_srcdir}/tests/data/cmdline/multi \
${top_srcdir}/tests/data/cmdline/oneline \
${top_srcdir}/tests/data/etc/kernel/cmdline \
${top_srcdir}/tests/data/etc/kernel/cmdline.d/00_empty.conf \
${top_srcdir}/tests/data/etc/kernel/cmdline.d/00_newline.conf \
${top_srcdir}/tests/data/etc/kernel/cmdline.d/10_first.conf \
${top_srcdir}/tests/data/etc/kernel/cmdline.d/20_second.conf \
${top_srcdir}/tests/data/etc/kernel/cmdline.d/30_third.conf \
${top_srcdir}/tests/data/cmdline_vendor_only/usr/share/kernel/cmdline.d/10_first.conf \
${top_srcdir}/tests/data/cmdline_vendor_only/usr/share/kernel/cmdline.d/20_second.conf \
${top_srcdir}/tests/data/cmdline_vendor_only/usr/share/kernel/cmdline.d/30_third.conf \
${top_srcdir}/tests/data/cmdline_vendor_merged/usr/share/kernel/cmdline.d/00_empty.conf \
${top_srcdir}/tests/data/cmdline_vendor_merged/usr/share/kernel/cmdline.d/00_newline.conf \
${top_srcdir}/tests/data/cmdline_vendor_merged/usr/share/kernel/cmdline.d/10_first.conf \
${top_srcdir}/tests/data/cmdline_vendor_merged/usr/share/kernel/cmdline.d/20_second.conf \
${top_srcdir}/tests/data/cmdline_vendor_merged/usr/share/kernel/cmdline.d/30_third.conf \
${top_srcdir}/tests/data/cmdline_vendor_merged/usr/share/kernel/cmdline.d/40_masked.conf \
${top_srcdir}/tests/data/cmdline_vendor_merged/etc/kernel/cmdline \
${top_srcdir}/tests/data/cmdline_vendor_merged/etc/kernel/cmdline.d/10_local_first.conf \
${top_srcdir}/tests/data/cmdline_vendor_merged/etc/kernel/cmdline.d/20_local_second.conf \
${top_srcdir}/tests/data/cmdline_vendor_merged/etc/kernel/cmdline.d/30_local_third.conf \
${top_srcdir}/tests/data/cmdline_vendor_merged/etc/kernel/cmdline.d/40_masked.conf \
${top_srcdir}/tests/data/gptmbr.bin \
${top_srcdir}/tests/data/gptmbr.bin.v2 \
${top_srcdir}/sgcheck.suppressions \
${top_srcdir}/data/clr-boot-manager-booted.service \
${top_srcdir}/man/clr-boot-manager.1
EXTRA_DIST = \
${top_srcdir}/README.md \
${top_srcdir}/LICENSE.LGPL2.1 \
${top_srcdir}/HACKING \
${top_srcdir}/findstatic.pl \
${top_srcdir}/tests/data/blobfile \
${top_srcdir}/tests/data/match \
${top_srcdir}/tests/data/match1 \
${top_srcdir}/tests/data/nomatch1 \
${top_srcdir}/tests/data/nomatch2 \
${top_srcdir}/tests/data/clear.os-release \
${top_srcdir}/tests/data/solus.os-release \
${top_srcdir}/tests/data/cmdline/comments \
${top_srcdir}/tests/data/cmdline/mangledmess \
${top_srcdir}/tests/data/cmdline/multi \
${top_srcdir}/tests/data/cmdline/oneline \
${top_srcdir}/tests/data/etc/kernel/cmdline \
${top_srcdir}/tests/data/etc/kernel/cmdline.d/00_empty.conf \
${top_srcdir}/tests/data/etc/kernel/cmdline.d/00_newline.conf \
${top_srcdir}/tests/data/etc/kernel/cmdline.d/10_first.conf \
${top_srcdir}/tests/data/etc/kernel/cmdline.d/20_second.conf \
${top_srcdir}/tests/data/etc/kernel/cmdline.d/30_third.conf \
${top_srcdir}/tests/data/cmdline_vendor_only/usr/share/kernel/cmdline.d/10_first.conf \
${top_srcdir}/tests/data/cmdline_vendor_only/usr/share/kernel/cmdline.d/20_second.conf \
${top_srcdir}/tests/data/cmdline_vendor_only/usr/share/kernel/cmdline.d/30_third.conf \
${top_srcdir}/tests/data/cmdline_vendor_merged/usr/share/kernel/cmdline.d/00_empty.conf \
${top_srcdir}/tests/data/cmdline_vendor_merged/usr/share/kernel/cmdline.d/00_newline.conf \
${top_srcdir}/tests/data/cmdline_vendor_merged/usr/share/kernel/cmdline.d/10_first.conf \
${top_srcdir}/tests/data/cmdline_vendor_merged/usr/share/kernel/cmdline.d/20_second.conf \
${top_srcdir}/tests/data/cmdline_vendor_merged/usr/share/kernel/cmdline.d/30_third.conf \
${top_srcdir}/tests/data/cmdline_vendor_merged/usr/share/kernel/cmdline.d/40_masked.conf \
${top_srcdir}/tests/data/cmdline_vendor_merged/etc/kernel/cmdline \
${top_srcdir}/tests/data/cmdline_vendor_merged/etc/kernel/cmdline.d/10_local_first.conf \
${top_srcdir}/tests/data/cmdline_vendor_merged/etc/kernel/cmdline.d/20_local_second.conf \
${top_srcdir}/tests/data/cmdline_vendor_merged/etc/kernel/cmdline.d/30_local_third.conf \
${top_srcdir}/tests/data/cmdline_vendor_merged/etc/kernel/cmdline.d/40_masked.conf \
${top_srcdir}/tests/data/gptmbr.bin \
${top_srcdir}/tests/data/gptmbr.bin.v2 \
${top_srcdir}/sgcheck.suppressions \
${top_srcdir}/data/clr-boot-manager-booted.service \
${top_srcdir}/man/clr-boot-manager.1
NULL =
CLEANFILES =
DISTCHECK_CONFIGURE_FLAGS = \
--with-systemdsystemunitdir="${distdir}/${libdir}/systemd/system"
--with-systemdsystemunitdir="${distdir}/${libdir}/systemd/system"
AM_CFLAGS = -fstack-protector -Wall -pedantic \
-Wstrict-prototypes -Wundef -fno-common \
-Werror-implicit-function-declaration \
-Wformat -Wformat-security -Werror=format-security \
-Wconversion -Wunused-variable -Wunreachable-code \
-Wall -W -D_FORTIFY_SOURCE=2 \
-Wno-missing-field-initializers \
-std=c11 \
-DSYSCONFDIR=\"$(sysconfdir)\"
AM_CFLAGS = -fstack-protector -Wall -pedantic \
-Wstrict-prototypes -Wundef -fno-common \
-Werror-implicit-function-declaration \
-Wformat -Wformat-security -Werror=format-security \
-Wconversion -Wunused-variable -Wunreachable-code \
-Wall -W -D_FORTIFY_SOURCE=2 \
-Wno-missing-field-initializers \
-std=c11 \
-DSYSCONFDIR=\"$(sysconfdir)\" \
-D_POSIX_C_SOURCE=201112L
AM_CPPFLAGS = \
-I $(top_srcdir)/src \
-I $(top_srcdir)/src/bootman \
-I $(top_srcdir)/src/cli \
-I $(top_srcdir)/src/bootloaders \
-I $(top_srcdir)/src/lib \
-I $(top_srcdir)/src/libnica/src/include \
-DTOP_DIR=\"$(abs_top_srcdir)\" \
-DTOP_BUILD_DIR=\"$(abs_top_builddir)\"
AM_CPPFLAGS = \
-I $(top_srcdir)/src \
-I $(top_srcdir)/src/bootman \
-I $(top_srcdir)/src/cli \
-I $(top_srcdir)/src/bootloaders \
-I $(top_srcdir)/src/lib \
-I $(top_srcdir)/src/libnica/src/include \
-isystem @efivar@ \
-isystem @gnuefi@ \
-isystem @gnuefi@/@host_cpu@ \
-DTOP_DIR=\"$(abs_top_srcdir)\" \
-DTOP_BUILD_DIR=\"$(abs_top_builddir)\"
AUTOMAKE_OPTIONS = color-tests parallel-tests
@@ -89,68 +94,76 @@ noinst_LTLIBRARIES = \
bin_PROGRAMS = clr-boot-manager
libcbm_la_SOURCES = \
src/bootloaders/bootloader.h \
src/bootloaders/systemd-class.h \
src/bootloaders/systemd-class.c \
src/bootloaders/systemd-boot.c \
src/bootloaders/grub2.c \
src/bootloaders/gummiboot.c \
src/bootloaders/goofiboot.c \
src/bootloaders/syslinux.c \
src/bootman/bootman.h \
src/bootman/bootman_private.h \
src/bootman/bootman.c \
src/bootman/kernel.c \
src/bootman/sysconfig.c \
src/bootman/timeout.c \
src/bootman/update.c \
src/lib/blkid_stub.h \
src/lib/blkid_stub.c \
src/lib/cmdline.h \
src/lib/cmdline.c \
src/lib/files.h \
src/lib/files.c \
src/lib/os-release.h \
src/lib/os-release.c \
src/lib/log.h \
src/lib/log.c \
src/lib/probe.h \
src/lib/probe.c \
src/lib/system_stub.h \
src/lib/system_stub.c \
src/lib/writer.h \
src/lib/writer.c \
src/lib/util.h \
src/lib/util.c
SOURCE_FILES = \
src/bootloaders/bootloader.h \
src/bootloaders/systemd-class.h \
src/bootloaders/systemd-class.c \
src/bootloaders/shim-systemd.c \
src/bootloaders/systemd-boot.c \
src/bootloaders/grub2.c \
src/bootloaders/gummiboot.c \
src/bootloaders/goofiboot.c \
src/bootloaders/syslinux.c \
src/bootman/bootman.h \
src/bootman/bootman_private.h \
src/bootman/bootman.c \
src/bootman/kernel.c \
src/bootman/sysconfig.c \
src/bootman/timeout.c \
src/bootman/update.c \
src/lib/blkid_stub.h \
src/lib/blkid_stub.c \
src/lib/cmdline.h \
src/lib/cmdline.c \
src/lib/files.h \
src/lib/files.c \
src/lib/os-release.h \
src/lib/os-release.c \
src/lib/log.h \
src/lib/log.c \
src/lib/probe.h \
src/lib/probe.c \
src/lib/system_stub.h \
src/lib/system_stub.c \
src/lib/writer.h \
src/lib/writer.c \
src/lib/util.h \
src/lib/util.c \
src/lib/bootvar.h \
src/lib/bootvar.c
libcbm_la_CFLAGS = \
-D_BOOTMAN_INTERNAL_ \
$(BLKID_CFLAGS) \
$(AM_CFLAGS)
libcbm_la_SOURCES = \
$(SOURCE_FILES)
libcbm_la_LIBADD = \
src/libnica/libnica.la
libcbm_la_CFLAGS = \
-D_BOOTMAN_INTERNAL_ \
$(BLKID_CFLAGS) \
$(AM_CFLAGS)
clr_boot_manager_SOURCES = \
src/cli/cli.h \
src/cli/cli.c \
src/cli/ops/update.h \
src/cli/ops/update.c \
src/cli/ops/timeout.h \
src/cli/ops/timeout.c \
src/cli/ops/report_booted.h \
src/cli/ops/report_booted.c \
src/cli/main.c
libcbm_la_LIBADD = \
src/libnica/libnica.la
clr_boot_manager_CFLAGS = \
$(BLKID_CFLAGS) \
$(AM_CFLAGS)
clr_boot_manager_SOURCES = \
src/cli/cli.h \
src/cli/cli.c \
src/cli/ops/update.h \
src/cli/ops/update.c \
src/cli/ops/timeout.h \
src/cli/ops/timeout.c \
src/cli/ops/report_booted.h \
src/cli/ops/report_booted.c \
src/cli/main.c
clr_boot_manager_LDADD = \
libcbm.la \
src/libnica/libnica.la \
$(BLKID_LIBS)
clr_boot_manager_CFLAGS = \
$(BLKID_CFLAGS) \
$(AM_CFLAGS)
clr_boot_manager_LDADD = \
libcbm.la \
src/libnica/libnica.la \
-lefiboot \
-lefivar \
$(BLKID_LIBS)
install-exec-hook:
perl ${top_srcdir}/findstatic.pl ${top_builddir}/src/*.o ${top_builddir}/src/*/*.o | grep -v Checking ||:
@@ -162,180 +175,196 @@ dist_systemdsystemunit_DATA = ${top_srcdir}/data/clr-boot-manager-booted.service
endif
manpagesdir = $(mandir)/man1
manpages_DATA = \
man/clr-boot-manager.1
manpages_DATA = \
man/clr-boot-manager.1
distclean-local:
rm -rf ${top_builddir}/tests/update_playground
TESTS = \
check_core \
check_cmdline \
check_files \
check_legacy \
check_os_release \
check_uefi \
check_grub2 \
check_select_bootloader \
check_probe
TESTS = \
check_core \
check_cmdline \
check_files \
check_legacy \
check_os_release \
check_uefi \
check_grub2 \
check_select_bootloader \
check_probe
check_PROGRAMS = $(TESTS)
check_core_SOURCES = \
tests/check-core.c \
tests/blkid-harness.h \
tests/system-harness.h \
tests/harness.h \
tests/harness.c
check_core_SOURCES = \
tests/check-core.c \
tests/blkid-harness.h \
tests/system-harness.h \
tests/harness.h \
tests/harness.c
check_core_CFLAGS = \
$(BLKID_CFLAGS) \
$(CHECK_CFLAGS) \
$(AM_CFLAGS)
check_core_CFLAGS = \
$(BLKID_CFLAGS) \
$(CHECK_CFLAGS) \
$(AM_CFLAGS)
check_core_LDADD = \
libcbm.la \
src/libnica/libnica.la \
$(BLKID_LIBS) \
$(CHECK_LIBS)
check_core_LDADD = \
libcbm.la \
src/libnica/libnica.la \
-lefiboot \
-lefivar \
$(BLKID_LIBS) \
$(CHECK_LIBS)
check_cmdline_SOURCES = \
tests/check-cmdline.c
check_cmdline_SOURCES = \
tests/check-cmdline.c
check_cmdline_CFLAGS = \
$(BLKID_CFLAGS) \
$(CHECK_CFLAGS) \
$(AM_CFLAGS)
check_cmdline_CFLAGS = \
$(BLKID_CFLAGS) \
$(CHECK_CFLAGS) \
$(AM_CFLAGS)
check_cmdline_LDADD = \
libcbm.la \
src/libnica/libnica.la \
$(BLKID_LIBS) \
$(CHECK_LIBS)
check_cmdline_LDADD = \
libcbm.la \
src/libnica/libnica.la \
-lefiboot \
-lefivar \
$(BLKID_LIBS) \
$(CHECK_LIBS)
check_files_SOURCES = \
tests/check-files.c \
tests/harness.h \
tests/harness.c
check_files_SOURCES = \
tests/check-files.c \
tests/harness.h \
tests/harness.c
check_files_CFLAGS = \
$(BLKID_CFLAGS) \
$(CHECK_CFLAGS) \
$(AM_CFLAGS)
check_files_CFLAGS = \
$(BLKID_CFLAGS) \
$(CHECK_CFLAGS) \
$(AM_CFLAGS)
check_files_LDADD = \
libcbm.la \
src/libnica/libnica.la \
$(BLKID_LIBS) \
$(CHECK_LIBS)
check_files_LDADD = \
libcbm.la \
src/libnica/libnica.la \
-lefiboot \
-lefivar \
$(BLKID_LIBS) \
$(CHECK_LIBS)
check_legacy_SOURCES = \
tests/check-legacy.c \
tests/blkid-harness.h \
tests/system-harness.h \
tests/harness.h \
tests/harness.c
check_legacy_SOURCES = \
tests/check-legacy.c \
tests/blkid-harness.h \
tests/system-harness.h \
tests/harness.h \
tests/harness.c
check_legacy_CFLAGS = \
$(BLKID_CFLAGS) \
$(CHECK_CFLAGS) \
$(AM_CFLAGS)
check_legacy_CFLAGS = \
$(BLKID_CFLAGS) \
$(CHECK_CFLAGS) \
$(AM_CFLAGS)
check_legacy_LDADD = \
libcbm.la \
src/libnica/libnica.la \
$(BLKID_LIBS) \
$(CHECK_LIBS)
check_legacy_LDADD = \
libcbm.la \
src/libnica/libnica.la \
-lefiboot \
-lefivar \
$(BLKID_LIBS) \
$(CHECK_LIBS)
check_os_release_SOURCES = \
tests/check-os-release.c
check_os_release_SOURCES = \
tests/check-os-release.c
check_os_release_CFLAGS = \
$(BLKID_CFLAGS) \
$(CHECK_CFLAGS) \
$(AM_CFLAGS)
check_os_release_CFLAGS = \
$(BLKID_CFLAGS) \
$(CHECK_CFLAGS) \
$(AM_CFLAGS)
check_os_release_LDADD = \
libcbm.la \
src/libnica/libnica.la \
$(BLKID_LIBS) \
$(CHECK_LIBS)
check_os_release_LDADD = \
libcbm.la \
src/libnica/libnica.la \
-lefiboot \
-lefivar \
$(BLKID_LIBS) \
$(CHECK_LIBS)
check_uefi_SOURCES = \
tests/check-uefi.c \
tests/blkid-harness.h \
tests/system-harness.h \
tests/harness.h \
tests/harness.c
check_uefi_SOURCES = \
tests/check-uefi.c \
tests/blkid-harness.h \
tests/system-harness.h \
tests/harness.h \
tests/harness.c
check_uefi_CFLAGS = \
$(BLKID_CFLAGS) \
$(CHECK_CFLAGS) \
$(AM_CFLAGS)
check_uefi_CFLAGS = \
$(BLKID_CFLAGS) \
$(CHECK_CFLAGS) \
$(AM_CFLAGS)
check_uefi_LDADD = \
libcbm.la \
src/libnica/libnica.la \
$(BLKID_LIBS) \
$(CHECK_LIBS)
check_uefi_LDADD = \
libcbm.la \
src/libnica/libnica.la \
-lefiboot \
-lefivar \
$(BLKID_LIBS) \
$(CHECK_LIBS)
check_grub2_SOURCES = \
tests/check-grub2.c \
tests/blkid-harness.h \
tests/system-harness.h \
tests/harness.h \
tests/harness.c
check_grub2_SOURCES = \
tests/check-grub2.c \
tests/blkid-harness.h \
tests/system-harness.h \
tests/harness.h \
tests/harness.c
check_grub2_CFLAGS = \
$(BLKID_CFLAGS) \
$(CHECK_CFLAGS) \
$(AM_CFLAGS)
check_grub2_CFLAGS = \
$(BLKID_CFLAGS) \
$(CHECK_CFLAGS) \
$(AM_CFLAGS)
check_grub2_LDADD = \
libcbm.la \
src/libnica/libnica.la \
$(BLKID_LIBS) \
$(CHECK_LIBS)
check_grub2_LDADD = \
libcbm.la \
src/libnica/libnica.la \
-lefiboot \
-lefivar \
$(BLKID_LIBS) \
$(CHECK_LIBS)
check_select_bootloader_SOURCES = \
tests/check-select-bootloader.c \
tests/blkid-harness.h \
tests/system-harness.h \
tests/harness.h \
tests/harness.c
check_select_bootloader_SOURCES = \
tests/check-select-bootloader.c \
tests/blkid-harness.h \
tests/system-harness.h \
tests/harness.h \
tests/harness.c
check_select_bootloader_CFLAGS = \
$(BLKID_CFLAGS) \
$(CHECK_CFLAGS) \
$(AM_CFLAGS)
check_select_bootloader_CFLAGS = \
$(BLKID_CFLAGS) \
$(CHECK_CFLAGS) \
$(AM_CFLAGS)
check_select_bootloader_LDADD = \
libcbm.la \
src/libnica/libnica.la \
$(BLKID_LIBS) \
$(CHECK_LIBS)
check_select_bootloader_LDADD = \
libcbm.la \
src/libnica/libnica.la \
-lefiboot \
-lefivar \
$(BLKID_LIBS) \
$(CHECK_LIBS)
check_probe_SOURCES = \
tests/check-probe.c \
tests/blkid-harness.h \
tests/system-harness.h \
tests/harness.h \
tests/harness.c
check_probe_SOURCES = \
tests/check-probe.c \
tests/blkid-harness.h \
tests/system-harness.h \
tests/harness.h \
tests/harness.c
check_probe_CFLAGS = \
$(BLKID_CFLAGS) \
$(CHECK_CFLAGS) \
$(AM_CFLAGS)
check_probe_LDADD = \
libcbm.la \
src/libnica/libnica.la \
$(BLKID_LIBS) \
$(CHECK_LIBS)
check_probe_CFLAGS = \
$(BLKID_CFLAGS) \
$(CHECK_CFLAGS) \
$(AM_CFLAGS)
check_probe_LDADD = \
libcbm.la \
src/libnica/libnica.la \
-lefiboot \
-lefivar \
$(BLKID_LIBS) \
$(CHECK_LIBS)
@VALGRIND_CHECK_RULES@
VALGRIND_SUPPRESSIONS_FILES = \
VALGRIND_SUPPRESSIONS_FILES = \
${abs_top_srcdir}/sgcheck.suppressions
+29 -4
View File
@@ -2,6 +2,7 @@ AC_INIT([clr-boot-manager], 1.5.5, [william.douglas@intel.com], [clr-boot-manage
AM_INIT_AUTOMAKE([-Wno-portability no-dist-gzip dist-xz foreign subdir-objects])
AC_PROG_CC
AC_PROG_CC_STDC
AC_CANONICAL_HOST
AC_CONFIG_HEADERS([config.h])
AC_PREFIX_DEFAULT(/usr/local)
AM_SILENT_RULES([yes])
@@ -42,7 +43,11 @@ AC_ARG_WITH([bootloader], AS_HELP_STRING([--with-bootloader=BOOTLOADER],
if test x$bootloader = "xauto"; then
AC_MSG_CHECKING([whether an EFI bootloader is available])
if test -e "/usr/lib/systemd/boot/efi"; then
bootloader="systemd-boot"
if test -e "/usr/lib/shim"; then
bootloader="shim-systemd-boot"
else
bootloader="systemd-boot"
fi
elif test -e "/usr/lib/goofiboot"; then
bootloader="goofiboot"
# use newer goofiboot, may be dual installed
@@ -50,13 +55,17 @@ if test x$bootloader = "xauto"; then
bootloader="gummiboot"
else
AC_MSG_WARN([Cannot find a valid EFI bootloader, defaulting to systemd-boot])
bootloader="systemd-boot"
bootloader="shim-systemd-boot"
fi
AC_MSG_RESULT([$bootloader])
fi
# Now test the option
if test x$bootloader = "xsystemd-boot"; then
if test x$bootloader = "xshim-systemd-boot"; then
have_shim_systemdboot="yes"
AC_DEFINE([HAVE_SHIM_SYSTEMD_BOOT], [1], [Using shim-systemd-boot])
AC_DEFINE([HAVE_SYSTEMD_BOOT], [1], [Adding systemd-boot])
elif test x$bootloader = "xsystemd-boot"; then
have_systemdboot="yes"
AC_DEFINE([HAVE_SYSTEMD_BOOT], [1], [Using systemd-boot])
elif test x$bootloader = "xgummiboot"; then
@@ -66,9 +75,10 @@ elif test x$bootloader = "xgoofiboot"; then
have_goofiboot="yes"
AC_DEFINE([HAVE_GOOFIBOOT], [1], [Using goofiboot])
else
AC_MSG_ERROR([Unknown bootloader, use: systemd-boot, gummiboot, or goofiboot])
AC_MSG_ERROR([Unknown bootloader, use: shim-systemd-boot, systemd-boot, gummiboot, or goofiboot])
fi
AM_CONDITIONAL([HAVE_SHIM_SYSTEMD_BOOT], [test x$have_shim_systemdboot = "xyes"])
AM_CONDITIONAL([HAVE_SYSTEMD_BOOT], [test x$have_systemdboot = "xyes"])
AM_CONDITIONAL([HAVE_GUMMIBOOT], [test x$have_gummiboot = "xyes"])
AM_CONDITIONAL([HAVE_GOOFIBOOT], [test x$have_goofiboot = "xyes"])
@@ -89,6 +99,19 @@ AC_SUBST(kernelmodulesdir)
AC_DEFINE_UNQUOTED(KERNEL_MODULES_DIRECTORY, "$kernelmodulesdir",
[The location of kernel modules in this OS configuration])
AC_ARG_WITH([gnu-efi], AS_HELP_STRING([--with-gnu-efi],
[the location of gnu-efi headers]), [gnuefi=${withval}],
[gnuefi="/usr/include/efi"])
AC_SUBST(gnuefi)
dnl DO NOT use PKG_CHECK_MODULES for efivar: it's headers do not compile with
dnl -pendantic --std=c11 with standard -I. Instead capture the directory and use
dnl -isystem (to avoid enforcement of the standards).
AC_ARG_WITH([efivar], AS_HELP_STRING([--with-efivar],
[the location of efivar headers]), [efivar=${withval}],
[efivar="/usr/include/efivar"])
AC_SUBST(efivar)
AC_ARG_WITH([kernel-namespace], AS_HELP_STRING([--with-kernel-namespace],
[the kernel path namespace to use]), [kernelnamespace=${withval}],
[kernelnamespace="org.clearlinux"])
@@ -168,6 +191,8 @@ AC_MSG_RESULT([
bootloader: ${bootloader}
kernel-dir: ${kerneldir}
kernel-modules-dir: ${kernelmodulesdir}
gnu-efi: ${gnuefi}
efivar: ${efivar}
kernel-namespace: ${kernelnamespace}
kernel-conf-dir: ${kernelconfdir}
vendor-kernel-conf-dir: ${vendorkernelconfdir}
+5 -2
View File
@@ -21,6 +21,7 @@
typedef bool (*boot_loader_init)(const BootManager *);
typedef bool (*boot_loader_install_kernel)(const BootManager *, const Kernel *);
typedef char *(*boot_loader_get_kernel_destination)(const BootManager *);
typedef bool (*boot_loader_remove_kernel)(const BootManager *, const Kernel *);
typedef bool (*boot_loader_set_default_kernel)(const BootManager *, const Kernel *kernel);
typedef bool (*boot_loader_needs_update)(const BootManager *);
@@ -43,8 +44,10 @@ typedef enum {
* Virtual BootLoader provider
*/
typedef struct BootLoader {
const char *name; /**<Name of the implementation */
boot_loader_init init; /**<Init function */
const char *name; /**<Name of the implementation */
boot_loader_init init; /**<Init function */
boot_loader_get_kernel_destination
get_kernel_destination; /**<Get location where bootloader expects the kernels to reside */
boot_loader_install_kernel install_kernel; /**<Install a given kernel */
boot_loader_remove_kernel remove_kernel; /**<Remove a given kernel */
boot_loader_set_default_kernel set_default_kernel; /**<Set the default kernel */
+14 -14
View File
@@ -23,20 +23,20 @@ static bool goofiboot_init(const BootManager *manager)
return sd_class_init(manager, &goofiboot_config);
}
__cbm_export__ const BootLoader goofiboot_bootloader = {.name = "goofiboot",
.init = goofiboot_init,
.install_kernel = sd_class_install_kernel,
.remove_kernel = sd_class_remove_kernel,
.set_default_kernel =
sd_class_set_default_kernel,
.needs_install = sd_class_needs_install,
.needs_update = sd_class_needs_update,
.install = sd_class_install,
.update = sd_class_update,
.remove = sd_class_remove,
.destroy = sd_class_destroy,
.get_capabilities =
sd_class_get_capabilities };
__cbm_export__ const BootLoader
goofiboot_bootloader = {.name = "goofiboot",
.init = goofiboot_init,
.get_kernel_destination = sd_class_get_kernel_destination,
.install_kernel = sd_class_install_kernel,
.remove_kernel = sd_class_remove_kernel,
.set_default_kernel = sd_class_set_default_kernel,
.needs_install = sd_class_needs_install,
.needs_update = sd_class_needs_update,
.install = sd_class_install,
.update = sd_class_update,
.remove = sd_class_remove,
.destroy = sd_class_destroy,
.get_capabilities = sd_class_get_capabilities };
/*
* Editor modelines - https://www.wireshark.org/tools/modelines.html
+4
View File
@@ -538,6 +538,10 @@ int grub2_get_capabilities(__cbm_unused__ const BootManager *manager)
__cbm_export__ const BootLoader grub2_bootloader = {.name = "grub2",
.init = grub2_init,
.get_kernel_destination = NULL, /* kernel
directory
only needed for EFI
booloaders */
.install_kernel = grub2_install_kernel,
.remove_kernel = grub2_remove_kernel,
.set_default_kernel = grub2_set_default_kernel,
+14 -14
View File
@@ -23,20 +23,20 @@ static bool gummiboot_init(const BootManager *manager)
return sd_class_init(manager, &gummiboot_config);
}
__cbm_export__ const BootLoader gummiboot_bootloader = {.name = "gummiboot",
.init = gummiboot_init,
.install_kernel = sd_class_install_kernel,
.remove_kernel = sd_class_remove_kernel,
.set_default_kernel =
sd_class_set_default_kernel,
.needs_install = sd_class_needs_install,
.needs_update = sd_class_needs_update,
.install = sd_class_install,
.update = sd_class_update,
.remove = sd_class_remove,
.destroy = sd_class_destroy,
.get_capabilities =
sd_class_get_capabilities };
__cbm_export__ const BootLoader
gummiboot_bootloader = {.name = "gummiboot",
.init = gummiboot_init,
.get_kernel_destination = sd_class_get_kernel_destination,
.install_kernel = sd_class_install_kernel,
.remove_kernel = sd_class_remove_kernel,
.set_default_kernel = sd_class_set_default_kernel,
.needs_install = sd_class_needs_install,
.needs_update = sd_class_needs_update,
.install = sd_class_install,
.update = sd_class_update,
.remove = sd_class_remove,
.destroy = sd_class_destroy,
.get_capabilities = sd_class_get_capabilities };
/*
* Editor modelines - https://www.wireshark.org/tools/modelines.html
+315
View File
@@ -0,0 +1,315 @@
/*
* This file is part of clr-boot-manager.
*
* Copyright © 2017 Intel Corporation
*
* clr-boot-manager is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
*/
#define _GNU_SOURCE
#include <linux/limits.h>
#include "bootloader.h"
#include "bootman.h"
#include "bootvar.h"
#include "config.h"
#include "files.h"
#include "nica/files.h"
#include "systemd-class.h"
#include <log.h>
/*
* This file implements 2-stage bootloader configuration in which shim is used as
* the first stage bootloader and systemd-boot as the second stage bootloader.
*
* This implementation uses the following ESP layout:
*
* /EFI/
* Boot/
* BOOTX64.EFI <-- this implementation never modifies the
* default fallback loader
*
* /org.clearlinux/
* bootloaderx64.efi <-- shim
* loaderx64.efi <-- systemd-boot bootloader
* mmx64.efi <-- MOK mgr
* fbx64.efi <-- MOK mgr
*
* kernel/ <-- kernels
* kernel-org.clearlinux.....
* ...
*
* /loader/ <-- systemd-boot config
* entries/ <-- boot menu entries
* Clear-linux...conf
* ...
* loader.conf <-- bootloader config
*
* Note that default bootloader at /EFI/Boot/BOOTX64.EFI is never modified.
* Instead, we create an EFI BootXXX variable and put it first in the BootOrder
* EFI variable.
*/
static char *shim_systemd_get_kernel_dst(const BootManager *);
static bool shim_systemd_install_kernel(const BootManager *, const Kernel *);
static bool shim_systemd_remove_kernel(const BootManager *, const Kernel *);
static bool shim_systemd_set_default_kernel(const BootManager *, const Kernel *);
static bool shim_systemd_needs_install(const BootManager *);
static bool shim_systemd_needs_update(const BootManager *);
static bool shim_systemd_install(const BootManager *);
static bool shim_systemd_update(const BootManager *);
static bool shim_systemd_remove(const BootManager *);
static bool shim_systemd_init(const BootManager *);
static void shim_systemd_destroy(const BootManager *);
static int shim_systemd_get_capabilities(const BootManager *);
__cbm_export__ const BootLoader
shim_systemd_bootloader = {.name = "systemd",
.init = shim_systemd_init,
.get_kernel_destination = shim_systemd_get_kernel_dst,
.install_kernel = shim_systemd_install_kernel,
.remove_kernel = shim_systemd_remove_kernel,
.set_default_kernel = shim_systemd_set_default_kernel,
.needs_install = shim_systemd_needs_install,
.needs_update = shim_systemd_needs_update,
.install = shim_systemd_install,
.update = shim_systemd_update,
.remove = shim_systemd_remove,
.destroy = shim_systemd_destroy,
.get_capabilities = shim_systemd_get_capabilities };
#if UINTPTR_MAX == 0xffffffffffffffff
#define EFI_SUFFIX "x64.efi"
#else
#define EFI_SUFFIX "ia32.efi"
#endif
/* Layout entries, see the layout description at the top of the file. */
#define SHIM_SRC_DIR "usr/lib/shim"
#define SHIM_SRC \
SHIM_SRC_DIR \
"/" \
"shim" EFI_SUFFIX
#define MM_SRC \
SHIM_SRC_DIR \
"/" \
"mm" EFI_SUFFIX
#define FB_SRC \
SHIM_SRC_DIR \
"/" \
"fb" EFI_SUFFIX
#define SYSTEMD_SRC_DIR "usr/lib/systemd/boot/efi"
#define SYSTEMD_SRC \
SYSTEMD_SRC_DIR \
"/" \
"systemd-boot" EFI_SUFFIX
#define DST_DIR "/" KERNEL_NAMESPACE
#define SHIM_DST \
DST_DIR \
"/" \
"bootloader" EFI_SUFFIX
#define SYSTEMD_DST \
DST_DIR \
"/" \
"loader" EFI_SUFFIX
#define KERNEL_DST_DIR DST_DIR "/kernel"
#define SYSTEMD_CONFIG_DIR "/loader"
#define SYSTEMD_CONFIG SYSTEMD_CONFIG_DIR "/loader.conf"
#define SYSTEMD_ENTRIES SYSTEMD_CONFIG_DIR "/entries"
static char *shim_src;
static char *shim_dst_host; /* as accessible by the CMB for file ops. */
static char *shim_dst_esp; /* absolute location of shim on the ESP. */
static char *systemd_src;
static char *systemd_dst_host;
extern void sd_class_set_get_kernel_destination_impl(char *(*)(const BootManager *));
static char *shim_systemd_get_kernel_dst(__cbm_unused__ const BootManager *manager)
{
return strdup(KERNEL_DST_DIR);
}
static bool shim_systemd_install_kernel(const BootManager *manager, const Kernel *kernel)
{
return sd_class_install_kernel(manager, kernel);
}
static bool shim_systemd_remove_kernel(const BootManager *manager, const Kernel *kernel)
{
return sd_class_remove_kernel(manager, kernel);
}
static bool shim_systemd_set_default_kernel(const BootManager *manager, const Kernel *kernel)
{
/* this writes systemd config. systemd has the configuration paths
* hardcoded, hence whatever sd_class is doing is OK. */
return sd_class_set_default_kernel(manager, kernel);
}
static bool exists_identical(const char *path, const char *spath)
{
if (!nc_file_exists(path))
return false;
if (spath && !cbm_files_match(path, spath))
return false;
return true;
}
static bool shim_systemd_needs_install(const BootManager *manager)
{
(void)manager;
if (!exists_identical(shim_dst_host, NULL))
return true;
if (!exists_identical(systemd_dst_host, NULL))
return true;
return false;
}
static bool shim_systemd_needs_update(const BootManager *manager)
{
(void)manager;
if (!exists_identical(shim_dst_host, shim_src))
return true;
if (!exists_identical(systemd_dst_host, systemd_src))
return true;
return false;
}
static bool make_layout(const BootManager *manager)
{
char *boot_root = boot_manager_get_boot_dir((BootManager *)manager);
char path[PATH_MAX];
snprintf(path, PATH_MAX, "%s%s", boot_root, DST_DIR);
if (!nc_mkdir_p(path, 00755)) {
goto fail;
}
snprintf(path, PATH_MAX, "%s%s", boot_root, KERNEL_DST_DIR);
if (!nc_mkdir_p(path, 00755)) {
goto fail;
}
snprintf(path, PATH_MAX, "%s%s", boot_root, SYSTEMD_ENTRIES);
if (!nc_mkdir_p(path, 00755)) {
goto fail;
}
return true;
fail:
LOG_FATAL("Failed to make dir: %s", path);
return false;
}
static bool shim_systemd_install(const BootManager *manager)
{
char varname[9];
if (!make_layout(manager)) {
LOG_FATAL("Cannot create layout");
return false;
}
if (!copy_file_atomic(shim_src, shim_dst_host, 00644)) {
LOG_FATAL("Cannot copy %s to %s", shim_src, shim_dst_host);
return false;
}
if (!copy_file_atomic(systemd_src, systemd_dst_host, 00644)) {
LOG_FATAL("Cannot copy %s to %s", systemd_src, systemd_dst_host);
return false;
}
if (bootvar_create(BOOT_DIRECTORY, shim_dst_esp, varname, 9)) {
LOG_FATAL("Cannot create EFI variable");
return false;
}
return true;
}
static bool shim_systemd_update(const BootManager *manager)
{
return shim_systemd_install(manager);
}
static bool shim_systemd_remove(const BootManager *manager)
{
(void)manager;
fprintf(stderr, "%s is not implemented\n", __func__);
return true;
}
static bool shim_systemd_init(const BootManager *manager)
{
size_t len;
char *prefix, *boot_root;
if (bootvar_init())
return false;
/* init systemd-class since we're reusing it for kernel install.
* specific values do not matter as long as sd_class is not used to
* install the bootloaders themselves. */
static BootLoaderConfig systemd_config = {.vendor_dir = "systemd",
.efi_dir = "/usr/lib/systemd/boot/efi",
.efi_blob = "systemd-boot" EFI_SUFFIX,
.name = "systemd-boot" };
sd_class_init(manager, &systemd_config);
sd_class_set_get_kernel_destination_impl(shim_systemd_get_kernel_dst);
prefix = strdup(boot_manager_get_prefix((BootManager *)manager));
len = strlen(prefix);
if (len > 0 && prefix[len - 1] == '/')
prefix[len - 1] = '\0';
shim_src = string_printf("%s/%s", prefix, SHIM_SRC);
systemd_src = string_printf("%s/%s", prefix, SYSTEMD_SRC);
boot_root = strdup(boot_manager_get_boot_dir((BootManager *)manager));
len = strlen(boot_root);
/* SHIM_DST and SYSTEMD_DST are defined with leading '/', take extra
* care to produce clean paths. */
if (len > 0 && boot_root[len - 1] == '/')
boot_root[len - 1] = '\0';
shim_dst_host = string_printf("%s%s", boot_root, SHIM_DST);
systemd_dst_host = string_printf("%s%s", boot_root, SYSTEMD_DST);
shim_dst_esp = SHIM_DST;
free(prefix);
free(boot_root);
return true;
}
static void shim_systemd_destroy(const BootManager *manager)
{
(void)manager;
free(shim_src);
free(systemd_src);
free(shim_dst_host);
free(systemd_dst_host);
bootvar_destroy();
return;
}
static int shim_systemd_get_capabilities(const BootManager *manager)
{
(void)manager;
return BOOTLOADER_CAP_GPT | BOOTLOADER_CAP_UEFI;
}
/*
* Editor modelines - https://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 8
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* vi: set shiftwidth=8 tabstop=8 expandtab:
* :indentSize=8:tabSize=8:noTabs=true:
*/
+24 -18
View File
@@ -38,11 +38,14 @@ typedef struct SdClassConfig {
char *efi_blob_dest;
char *default_path_efi_blob;
char *loader_config;
char *kernel_dir;
} SdClassConfig;
static SdClassConfig sd_class_config = { 0 };
static BootLoaderConfig *sd_config = NULL;
static char *(*get_kernel_destination_impl)(const BootManager *);
#define FREE_IF_SET(x) \
{ \
if (x) { \
@@ -65,6 +68,8 @@ bool sd_class_init(const BootManager *manager, BootLoaderConfig *config)
sd_config = config;
get_kernel_destination_impl = sd_class_get_kernel_destination;
/* Cache all of these to save useless allocs of the same paths later */
base_path = boot_manager_get_boot_dir((BootManager *)manager);
OOM_CHECK_RET(base_path, false);
@@ -112,9 +117,16 @@ bool sd_class_init(const BootManager *manager, BootLoaderConfig *config)
OOM_CHECK_RET(loader_config, false);
sd_class_config.loader_config = loader_config;
sd_class_config.kernel_dir = "/EFI/" KERNEL_NAMESPACE;
return true;
}
void sd_class_set_get_kernel_destination_impl(char *(*impl)(const BootManager *))
{
get_kernel_destination_impl = impl;
}
void sd_class_destroy(__cbm_unused__ const BootManager *manager)
{
FREE_IF_SET(sd_class_config.efi_dir);
@@ -151,7 +163,7 @@ static char *get_entry_path_for_kernel(BootManager *manager, const Kernel *kerne
NULL);
}
static bool sd_class_ensure_dirs(__cbm_unused__ const BootManager *manager)
static bool sd_class_ensure_dirs(void)
{
if (!nc_mkdir_p(sd_class_config.efi_dir, 00755)) {
LOG_FATAL("Failed to create %s: %s", sd_class_config.efi_dir, strerror(errno));
@@ -174,6 +186,11 @@ static bool sd_class_ensure_dirs(__cbm_unused__ const BootManager *manager)
return true;
}
char *sd_class_get_kernel_destination(__cbm_unused__ const BootManager *manager)
{
return strdup(sd_class_config.kernel_dir);
}
bool sd_class_install_kernel(const BootManager *manager, const Kernel *kernel)
{
if (!manager || !kernel) {
@@ -187,12 +204,6 @@ bool sd_class_install_kernel(const BootManager *manager, const Kernel *kernel)
conf_path = get_entry_path_for_kernel((BootManager *)manager, kernel);
/* Ensure all the relevant directories exist */
if (!sd_class_ensure_dirs(manager)) {
LOG_FATAL("Failed to create required directories");
return false;
}
if (!cbm_writer_open(writer)) {
DECLARE_OOM();
abort();
@@ -210,14 +221,14 @@ bool sd_class_install_kernel(const BootManager *manager, const Kernel *kernel)
/* Standard title + linux lines */
cbm_writer_append_printf(writer, "title %s\n", os_name);
cbm_writer_append_printf(writer,
"linux /EFI/%s/%s\n",
KERNEL_NAMESPACE,
"linux %s/%s\n",
get_kernel_destination_impl(manager),
kernel->target.path);
/* Optional initrd */
if (kernel->target.initrd_path) {
cbm_writer_append_printf(writer,
"initrd /EFI/%s/%s\n",
KERNEL_NAMESPACE,
"initrd %s/%s\n",
get_kernel_destination_impl(manager),
kernel->target.initrd_path);
}
/* Add the root= section */
@@ -290,11 +301,6 @@ bool sd_class_set_default_kernel(const BootManager *manager, const Kernel *kerne
return false;
}
if (!sd_class_ensure_dirs(manager)) {
LOG_FATAL("Failed to create required directories for %s", sd_config->name);
return false;
}
autofree(char) *item_name = NULL;
int timeout = 0;
const char *prefix = NULL;
@@ -404,7 +410,7 @@ bool sd_class_install(const BootManager *manager)
return false;
}
if (!sd_class_ensure_dirs(manager)) {
if (!sd_class_ensure_dirs()) {
LOG_FATAL("Failed to create required directories for %s", sd_config->name);
return false;
}
@@ -439,7 +445,7 @@ bool sd_class_update(const BootManager *manager)
if (!manager) {
return false;
}
if (!sd_class_ensure_dirs(manager)) {
if (!sd_class_ensure_dirs()) {
LOG_FATAL("Failed to create required directories for %s", sd_config->name);
return false;
}
+2
View File
@@ -29,6 +29,8 @@ typedef struct BootLoaderConfig {
const char *name;
} BootLoaderConfig;
char *sd_class_get_kernel_destination(const BootManager *manager);
bool sd_class_install_kernel(const BootManager *manager, const Kernel *kernel);
bool sd_class_remove_kernel(const BootManager *manager, const Kernel *kernel);
+4 -1
View File
@@ -31,6 +31,7 @@
* Total "usable" bootloaders
*/
extern const BootLoader grub2_bootloader;
extern const BootLoader shim_systemd_bootloader;
extern const BootLoader systemd_bootloader;
extern const BootLoader gummiboot_bootloader;
extern const BootLoader goofiboot_bootloader;
@@ -41,7 +42,9 @@ extern const BootLoader syslinux_bootloader;
*/
const BootLoader *bootman_known_loaders[] =
{ &grub2_bootloader, /**<Always place first to allow syslinux to override */
#if defined(HAVE_SYSTEMD_BOOT)
#if defined(HAVE_SHIM_SYSTEMD_BOOT)
&shim_systemd_bootloader,
#elif defined(HAVE_SYSTEMD_BOOT)
&systemd_bootloader,
#elif defined(HAVE_GUMMIBOOT)
&gummiboot_bootloader,
+30 -43
View File
@@ -592,36 +592,26 @@ bool boot_manager_install_kernel_internal(const BootManager *manager, const Kern
autofree(char) *base_path = NULL;
autofree(char) *initrd_target = NULL;
const char *initrd_source = NULL;
bool is_uefi = false;
autofree(char) *efi_boot_dir = NULL;
int is_uefi = (manager->bootloader->get_capabilities(manager) & BOOTLOADER_CAP_UEFI);
autofree(char) *efi_boot_dir =
is_uefi ? manager->bootloader->get_kernel_destination(manager) : NULL;
assert(manager != NULL);
assert(kernel != NULL);
if (is_uefi && !efi_boot_dir)
return false;
/* Boot path */
base_path = boot_manager_get_boot_dir((BootManager *)manager);
OOM_CHECK_RET(base_path, false);
/* Determine if UEFI is in use */
if ((manager->bootloader->get_capabilities(manager) & BOOTLOADER_CAP_UEFI) ==
BOOTLOADER_CAP_UEFI) {
is_uefi = true;
efi_boot_dir = nc_build_case_correct_path(base_path, "EFI", KERNEL_NAMESPACE, NULL);
}
/* For UEFI kernels we namespace into /EFI/$NEEDLE, i.e. /EFI/org.clearlinux */
if (is_uefi) {
/* Ensure namespace directory exists */
if (!nc_mkdir_p(efi_boot_dir, 00755)) {
LOG_FATAL("Failed to create namespace directory: %s %s",
efi_boot_dir,
strerror(errno));
return false;
}
kfile_target = string_printf("%s/%s", efi_boot_dir, kernel->target.path);
} else {
kfile_target = string_printf("%s/%s", base_path, kernel->target.legacy_path);
}
/* for UEFI, the kernel location is prefixed with efi_boot_dir which is
* guaranteed to start with '/' since it's its absolute path on ESP. */
kfile_target = string_printf("%s%s/%s",
base_path,
(is_uefi ? efi_boot_dir : ""),
(is_uefi ? kernel->target.path : kernel->target.legacy_path));
/* Now copy the kernel file to it's new location */
if (!cbm_files_match(kernel->source.path, kfile_target)) {
@@ -641,11 +631,10 @@ bool boot_manager_install_kernel_internal(const BootManager *manager, const Kern
return true;
}
if (is_uefi) {
initrd_target = string_printf("%s/%s", efi_boot_dir, kernel->target.initrd_path);
} else {
initrd_target = string_printf("%s/%s", base_path, kernel->target.initrd_path);
}
initrd_target = string_printf("%s%s/%s",
base_path,
(is_uefi ? efi_boot_dir : ""),
kernel->target.initrd_path);
if (!cbm_files_match(initrd_source, initrd_target)) {
if (!copy_file_atomic(initrd_source, initrd_target, 00644)) {
@@ -676,33 +665,31 @@ bool boot_manager_remove_kernel_internal(const BootManager *manager, const Kerne
autofree(char) *kfile_target = NULL;
autofree(char) *base_path = NULL;
autofree(char) *initrd_target = NULL;
bool is_uefi = false;
autofree(char) *efi_boot_dir = NULL;
int is_uefi = (manager->bootloader->get_capabilities(manager) & BOOTLOADER_CAP_UEFI);
autofree(char) *efi_boot_dir =
is_uefi ? manager->bootloader->get_kernel_destination(manager) : NULL;
assert(manager != NULL);
assert(kernel != NULL);
/* if it's UEFI, then bootloader->get_kernel_dst() must return a value. */
if (is_uefi && !efi_boot_dir)
return false;
/* Boot path */
base_path = boot_manager_get_boot_dir((BootManager *)manager);
OOM_CHECK_RET(base_path, false);
/* Determine if UEFI is in use */
if ((manager->bootloader->get_capabilities(manager) & BOOTLOADER_CAP_UEFI) ==
BOOTLOADER_CAP_UEFI) {
is_uefi = true;
efi_boot_dir = nc_build_case_correct_path(base_path, "EFI", KERNEL_NAMESPACE, NULL);
}
/* Remove old blobs */
if (is_uefi) {
kfile_target = string_printf("%s/%s", efi_boot_dir, kernel->target.path);
} else {
kfile_target = string_printf("%s/%s", base_path, kernel->target.legacy_path);
}
kfile_target = string_printf("%s%s/%s",
base_path,
(is_uefi ? efi_boot_dir : ""),
(is_uefi ? kernel->target.path : kernel->target.legacy_path));
if (kernel->source.initrd_file) {
initrd_target = string_printf("%s/%s",
is_uefi ? efi_boot_dir : base_path,
initrd_target = string_printf("%s%s/%s",
base_path,
(is_uefi ? efi_boot_dir : ""),
kernel->target.initrd_path);
}
+456
View File
@@ -0,0 +1,456 @@
/*
* This file is part of clr-boot-manager.
*
* Copyright © 2017 Intel Corporation
*
* clr-boot-manager is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
*/
#define _GNU_SOURCE
#include "bootvar.h"
#include <endian.h>
/* Workaround for using --std=c11 in CBM. Provide "relaxed" defines which efivar
* expects. */
#define BYTE_ORDER __BYTE_ORDER
#define LITTLE_ENDIAN __LITTLE_ENDIAN
#define BIG_ENDIAN __BIG_ENDIAN
#include <alloca.h>
#include <blkid.h>
#include <ctype.h>
#include <efi.h>
#include <efiboot.h>
#include <efilib.h>
#include <efivar.h>
#include <errno.h>
#include <log.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/sysmacros.h>
/* 1K is the limit for boot var storage that efivar defines. it should be
* enough. actual space occupied is normally >2 times less. */
#define BOOT_VAR_MAX 1024
/* env var to turn on the test mode. if set to "yes", turns off any side-effects
* functions defined in this file may have: the call will always succeed without
* side effects. */
#define CBM_BOOTVAR_TEST_MODE_VAR "CBM_BOOTVAR_TEST_MODE"
typedef struct boot_rec boot_rec_t;
struct boot_rec {
char *name;
int num;
unsigned char *data;
boot_rec_t *next;
};
static boot_rec_t *boot_recs;
static int boot_recs_cnt;
static int test_mode = 0;
static void bootvar_free_boot_recs(void)
{
boot_rec_t *p, *c;
c = boot_recs;
if (!c)
return;
boot_recs = NULL;
do {
p = c;
c = c->next;
free(p);
} while (c);
}
static void bootvar_print_boot_recs(void) __attribute__((unused));
static void bootvar_print_boot_recs(void)
{
boot_rec_t *c = boot_recs;
if (!c)
return;
do {
fprintf(stderr, "Boot record #%d: %s\n", c->num, c->name);
} while ((c = c->next));
}
/* enumerates boot recs and initializes boot_recs and boot_recs_cnt. */
static int bootvar_read_boot_recs(void)
{
int res;
efi_guid_t *guid = NULL;
char *name = NULL;
boot_rec_t *p = NULL, *c;
int i = 0;
bootvar_free_boot_recs();
while ((res = efi_get_next_variable_name(&guid, &name)) > 0) {
char *num_end;
if (strncmp(name, "Boot", 4))
continue;
if (!isxdigit(name[4]) || !isxdigit(name[5]) || !isxdigit(name[6]) ||
!isxdigit(name[7]))
continue;
if (memcmp(guid, &efi_guid_global, sizeof(efi_guid_t)))
continue;
c = (boot_rec_t *)malloc(sizeof(boot_rec_t));
memset(c, 0, sizeof(boot_rec_t));
c->name = strdup(name);
c->num = (int)strtol(name + 4, &num_end, 16);
if (num_end - name - 4 != 4)
continue;
if (!boot_recs) {
boot_recs = p = c;
} else {
p->next = c;
p = c;
}
i++;
}
if (res < 0) {
LOG_FATAL("efi_get_next_variable_name() failed: %s", strerror(errno));
return -EBOOT_VAR_ERR;
}
boot_recs_cnt = i;
return 0;
}
/* given the record, puts it first in the boot order (via BootOrder EFI
* variable). */
static int bootvar_push_to_boot_order(boot_rec_t *rec)
{
uint16_t number;
uint16_t *boot_order;
uint16_t *new_boot_order;
size_t boot_order_size;
size_t new_boot_order_size;
uint32_t boot_order_attrs;
unsigned int i;
int found = 0;
if (!rec || !rec->name)
return -EBOOT_VAR_ERR;
if (efi_get_variable(EFI_GLOBAL_GUID,
"BootOrder",
(uint8_t **)&boot_order,
&boot_order_size,
&boot_order_attrs)) {
LOG_FATAL("efi_get_variable() failed: %s", strerror(errno));
return -EBOOT_VAR_ERR;
}
sscanf(rec->name, "Boot%04hX", &number);
/* read as uint16_t, hence twice less the returned size */
boot_order_size >>= 1;
for (i = 0; i < boot_order_size; i++) {
if (boot_order[i] == number) {
found = 1;
break;
}
}
if (!found) {
new_boot_order_size = boot_order_size + 1;
new_boot_order = (uint16_t *)malloc(new_boot_order_size * sizeof(uint16_t));
new_boot_order[0] = number;
memcpy(new_boot_order + 1, boot_order, boot_order_size * sizeof(uint16_t));
} else {
uint16_t *c;
new_boot_order = (uint16_t *)malloc(boot_order_size * sizeof(uint16_t));
new_boot_order[0] = number;
c = new_boot_order + 1;
for (i = 0; i < boot_order_size; i++) {
if (boot_order[i] != number) {
*c = boot_order[i];
c++;
}
}
new_boot_order_size = (size_t)(c - new_boot_order);
}
new_boot_order_size <<= 1;
if (efi_set_variable(EFI_GLOBAL_GUID,
"BootOrder",
(uint8_t *)new_boot_order,
new_boot_order_size,
boot_order_attrs,
0644)) {
LOG_FATAL("efi_set_variable() failed: %s", strerror(errno));
return -EBOOT_VAR_ERR;
}
return 0;
}
static int cmp(const void *a, const void *b)
{
return *((int *)a) - *((int *)b);
}
/* finds the first available free number for a boot var. */
static int bootvar_find_free_no(void)
{
int *nums;
int res;
int i = 0;
boot_rec_t *c = boot_recs;
size_t cnt;
if (!boot_recs)
return -1;
if (!boot_recs_cnt)
return 0; /* no records. */
cnt = (size_t)boot_recs_cnt;
nums = (int *)alloca(sizeof(int) * cnt);
memset(nums, 0, sizeof(int) * cnt);
do {
nums[i] = c->num;
i++;
} while ((c = c->next));
qsort(nums, cnt, sizeof(int), cmp);
for (i = 0, res = 0; i < boot_recs_cnt; i++, res++) {
if (res < nums[i])
break;
}
if (res == nums[boot_recs_cnt - 1])
res++; /* no gap. */
return res;
}
/* finds and returns boot rec whose value is data of size. NULL if not found. */
static boot_rec_t *bootvar_find_boot_rec(uint8_t *data, size_t size)
{
boot_rec_t *c = boot_recs;
boot_rec_t *res = NULL;
uint8_t *cdata;
size_t csize;
uint32_t cattr;
if (!boot_recs || !boot_recs_cnt)
return NULL;
do {
if (efi_get_variable(EFI_GLOBAL_GUID, c->name, &cdata, &csize, &cattr) < 0) {
LOG_ERROR("efi_get_variable() failed: %s", strerror(errno));
continue;
}
if (csize == size && !memcmp(cdata, data, csize)) {
res = c;
break;
}
} while ((c = c->next));
return res;
}
typedef struct part_info {
char disk_path[PATH_MAX];
int part_no;
char part_type[36 + 1]; /* GUID string, hyphen notation */
} part_info_t;
/* given the location of the ESP mount point, returns the partition information
* needed to create boot variable which points to that bootloader. */
static int bootvar_get_part_info(const char *path, part_info_t *pi)
{
blkid_probe probe;
blkid_partition part;
blkid_partlist parts;
struct stat st;
dev_t disk_dev;
char disk_path[PATH_MAX];
const char *part_type;
if (stat(path, &st)) {
LOG_FATAL("stat() failed on %s: %s", path, strerror(errno));
return -EBOOT_VAR_ERR;
}
strcpy(disk_path, "/dev/");
if (blkid_devno_to_wholedisk(st.st_dev, disk_path + 5, PATH_MAX - 5, &disk_dev)) {
LOG_FATAL("blkid_devno_to_wholedisk() error");
return -EBOOT_VAR_ERR;
}
if (!(probe = blkid_new_probe_from_filename(disk_path))) {
LOG_FATAL("blkid_new_probe_from_filename() error");
return -EBOOT_VAR_ERR;
}
if (blkid_probe_enable_partitions(probe, 1)) {
LOG_FATAL("blkid_probe_enable_partitions() error");
return -EBOOT_VAR_ERR;
}
if (!(parts = blkid_probe_get_partitions(probe))) {
LOG_FATAL("blkid_probe_get_partitions() error");
return -EBOOT_VAR_ERR;
}
if (!(part = blkid_partlist_devno_to_partition(parts, st.st_dev))) {
LOG_FATAL("blkid_partlist_devno_to_partition() error");
return -EBOOT_VAR_ERR;
}
if ((pi->part_no = blkid_partition_get_partno(part)) < 0) {
LOG_FATAL("blkid_partition_get_partno() error");
return -EBOOT_VAR_ERR;
}
part_type = blkid_partition_get_type_string(part);
if (!part_type) {
LOG_FATAL("blkid_partition_get_type_string() returned NULL");
return -EBOOT_VAR_ERR;
} else if (strlen(part_type) != 36) {
LOG_FATAL("partition type does not seem to be a GUID: %s", part_type);
return -EBOOT_VAR_ERR;
}
snprintf(pi->disk_path, strlen(disk_path) + 1, "%s", disk_path);
snprintf(pi->part_type, 36 + 1, "%s", part_type);
blkid_free_probe(probe);
return 0;
}
/* attempts to look up existing record, otherwise creates a new one. */
static boot_rec_t *bootvar_add_boot_rec(uint8_t *data, size_t len)
{
char name[9]; /* variable name, e.g. "BootXXXX". */
int slot;
uint32_t attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS |
EFI_VARIABLE_RUNTIME_ACCESS;
boot_rec_t *c, *res = bootvar_find_boot_rec(data, len);
if (res)
return res;
/* no such record, create one. */
slot = bootvar_find_free_no();
if (slot < 0)
return NULL;
if (snprintf(name, 9, "Boot%04X", slot) > 8)
return NULL;
if (efi_set_variable(EFI_GLOBAL_GUID, name, data, len, attr, 0644) < 0) {
LOG_FATAL("efi_set_variable() failed: %s", strerror(errno));
return NULL;
}
/* re-read the records and find the variable that was just created. */
if (bootvar_read_boot_recs() < 0)
return NULL;
if (!boot_recs)
return NULL; /* something went terribly wrong. */
c = boot_recs;
do {
if (!strcmp(c->name, name)) {
res = c;
break;
}
} while ((c = c->next));
return res;
}
int bootvar_create(const char *esp_mount_path, const char *bootloader_esp_path, char *varname,
size_t size)
{
part_info_t pi;
uint8_t fdev_path[PATH_MAX];
uint8_t data[BOOT_VAR_MAX]; /* this is what efivar supports and it should be
enough. */
long int len;
boot_rec_t *rec;
if (test_mode)
return 0;
if (bootvar_get_part_info(esp_mount_path, &pi))
return -1;
len = efi_generate_file_device_path_from_esp(fdev_path,
PATH_MAX,
pi.disk_path,
pi.part_no,
bootloader_esp_path,
EFIBOOT_ABBREV_HD);
if (len < 0) {
LOG_FATAL("efi_generate_file_device_path_from_esp() failed: %s", strerror(errno));
return -EBOOT_VAR_ERR;
}
len = efi_loadopt_create(data,
BOOT_VAR_MAX,
LOAD_OPTION_ACTIVE,
(void *)fdev_path,
len,
(unsigned char *)"Linux bootloader",
NULL,
0);
if (len < 0) {
LOG_FATAL("efi_loadopt_create() failed: %s", strerror(errno));
return -EBOOT_VAR_ERR;
}
rec = bootvar_add_boot_rec(data, (size_t)len);
if (!rec)
return -EBOOT_VAR_ERR;
if (bootvar_push_to_boot_order(rec))
return -EBOOT_VAR_ERR;
if (varname && size) {
size_t len = strlen(rec->name);
if (len < size) {
snprintf(varname, len + 1, "%s", rec->name);
} else {
LOG_ERROR("%lu bytes is not enough. Need %lu.", size, len);
}
}
return 0;
}
int bootvar_init(void)
{
char *test_mode_env = getenv(CBM_BOOTVAR_TEST_MODE_VAR);
if (test_mode_env && !strncmp(test_mode_env, "yes", 4)) {
LOG_INFO("EFI variables support is disabled: " CBM_BOOTVAR_TEST_MODE_VAR " is set");
test_mode = 1;
}
if (test_mode)
return 0;
if (efi_variables_supported() < 0)
return -EBOOT_VAR_NOSUP;
if (bootvar_read_boot_recs() < 0)
return -EBOOT_VAR_ERR;
return 0;
}
void bootvar_destroy(void)
{
if (test_mode)
return;
bootvar_free_boot_recs();
}
/* vim: set nosi noai cin ts=8 sw=8 et tw=80: */
+21
View File
@@ -0,0 +1,21 @@
/*
* This file is part of clr-boot-manager.
*
* Copyright © 2017 Intel Corporation
*
* clr-boot-manager is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
*/
#include <stdlib.h>
#define EBOOT_VAR_ERR 1 /* general error */
#define EBOOT_VAR_NOSUP 127 /* EFI vars not supported */
int bootvar_init(void);
void bootvar_destroy(void);
int bootvar_create(const char *, const char *, char *, size_t);
/* vim: set nosi noai cin ts=8 sw=8 et tw=80: */
+3 -3
View File
@@ -59,9 +59,9 @@ char *get_parent_disk(char *path);
char *get_legacy_boot_device(char *path);
/**
* Determine if the files match in content by comparing
* their checksums
*/
* Determine if the files match in content by comparing
* their checksums
*/
bool cbm_files_match(const char *p1, const char *p2);
/**
+3
View File
@@ -134,6 +134,9 @@ int main(void)
setenv("CBM_DEBUG", "1", 1);
cbm_log_init(stderr);
/* Turn off the EFI variable manipulation. */
setenv("CBM_BOOTVAR_TEST_MODE", "yes", 1);
s = core_suite();
sr = srunner_create(s);
srunner_run_all(sr, CK_VERBOSE);
+3
View File
@@ -430,6 +430,9 @@ int main(void)
setenv("CBM_DEBUG", "1", 1);
cbm_log_init(stderr);
/* Turn off the EFI variable manipulation. */
setenv("CBM_BOOTVAR_TEST_MODE", "yes", 1);
cbm_blkid_set_vtable(&BlkidTestOps);
cbm_system_set_vtable(&SystemTestOps);
+3
View File
@@ -110,6 +110,9 @@ int main(void)
setenv("CBM_DEBUG", "1", 1);
cbm_log_init(stderr);
/* Turn off the EFI variable manipulation. */
setenv("CBM_BOOTVAR_TEST_MODE", "yes", 1);
s = core_suite();
sr = srunner_create(s);
srunner_run_all(sr, CK_VERBOSE);
+3
View File
@@ -261,6 +261,9 @@ int main(void)
setenv("CBM_DEBUG", "1", 1);
cbm_log_init(stderr);
/* Turn off the EFI variable manipulation. */
setenv("CBM_BOOTVAR_TEST_MODE", "yes", 1);
cbm_blkid_set_vtable(&blkid_ops);
cbm_system_set_vtable(&SystemTestOps);
+3
View File
@@ -294,6 +294,9 @@ int main(void)
setenv("CBM_DEBUG", "1", 1);
cbm_log_init(stderr);
/* Turn off the EFI variable manipulation. */
setenv("CBM_BOOTVAR_TEST_MODE", "yes", 1);
cbm_blkid_set_vtable(&blkid_ops);
cbm_system_set_vtable(&SystemTestOps);
+3
View File
@@ -73,6 +73,9 @@ int main(void)
setenv("CBM_DEBUG", "1", 1);
cbm_log_init(stderr);
/* Turn off the EFI variable manipulation. */
setenv("CBM_BOOTVAR_TEST_MODE", "yes", 1);
s = core_suite();
sr = srunner_create(s);
srunner_run_all(sr, CK_VERBOSE);
+3
View File
@@ -241,6 +241,9 @@ int main(void)
setenv("CBM_DEBUG", "1", 1);
cbm_log_init(stderr);
/* Turn off the EFI variable manipulation. */
setenv("CBM_BOOTVAR_TEST_MODE", "yes", 1);
s = core_suite();
sr = srunner_create(s);
srunner_run_all(sr, CK_VERBOSE);
+3
View File
@@ -441,6 +441,9 @@ int main(void)
setenv("CBM_DEBUG", "1", 1);
cbm_log_init(stderr);
/* Turn off the EFI variable manipulation. */
setenv("CBM_BOOTVAR_TEST_MODE", "yes", 1);
s = core_suite();
sr = srunner_create(s);
srunner_run_all(sr, CK_VERBOSE);
+3
View File
@@ -453,6 +453,9 @@ int main(void)
setenv("CBM_DEBUG", "1", 1);
cbm_log_init(stderr);
/* Turn off the EFI variable manipulation. */
setenv("CBM_BOOTVAR_TEST_MODE", "yes", 1);
cbm_blkid_set_vtable(&BlkidTestOps);
cbm_system_set_vtable(&SystemTestOps);
+38 -6
View File
@@ -14,6 +14,7 @@
#include <assert.h>
#include <check.h>
#include <errno.h>
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
@@ -59,15 +60,20 @@
*/
/**
* Systemd support
* Systemd support, including shim-systemd two-stage
*/
#if defined(HAVE_SYSTEMD_BOOT)
#if defined(HAVE_SHIM_SYSTEMD_BOOT)
#define ESP_BOOT_DIR BOOT_FULL "/" KERNEL_NAMESPACE
#define ESP_BOOT_STUB ESP_BOOT_DIR "/bootloader" EFI_STUB_SUFFIX_L
#define SHIM_BOOT_COPY_DIR PLAYGROUND_ROOT "/usr/lib/shim"
#else
#define ESP_BOOT_DIR EFI_START "/systemd"
#define ESP_BOOT_STUB ESP_BOOT_DIR "/systemd-boot" EFI_STUB_SUFFIX_L
#endif /* HAVE_SHIM_SYSTEMD_BOOT */
#define BOOT_COPY_TARGET PLAYGROUND_ROOT "/usr/lib/systemd/boot/efi/systemd-boot" EFI_STUB_SUFFIX_L
#define BOOT_COPY_DIR PLAYGROUND_ROOT "/usr/lib/systemd/boot/efi"
/**
* gummiboot support
*/
@@ -126,17 +132,21 @@ static void push_syslinux(void)
void confirm_bootloader(void)
{
#if !defined(HAVE_SHIM_SYSTEMD_BOOT)
fail_if(!noisy_file_exists(EFI_STUB_MAIN), "Main EFI stub missing");
#endif
fail_if(!noisy_file_exists(ESP_BOOT_DIR), "ESP target directory missing");
fail_if(!noisy_file_exists(ESP_BOOT_STUB), "ESP target stub missing");
}
bool confirm_bootloader_match(void)
{
#if !defined(HAVE_SHIM_SYSTEMD_BOOT)
if (!cbm_files_match(BOOT_COPY_TARGET, EFI_STUB_MAIN)) {
fprintf(stderr, "EFI_STUB_MAIN doesn't match the source\n");
return false;
}
#endif /* !HAVE_SHIM_SYSTEMD_BOOT */
if (!cbm_files_match(BOOT_COPY_TARGET, ESP_BOOT_STUB)) {
fprintf(stderr, "ESP_BOOT_STUB(vendor) doesn't match the source\n");
return false;
@@ -322,6 +332,24 @@ bool push_bootloader_update(int revision)
fprintf(stderr, "Failed to update bootloader: %s\n", strerror(errno));
return false;
}
#if defined(HAVE_SHIM_SYSTEMD_BOOT)
{
int i;
char path[PATH_MAX];
char *files[3] = { "fb", "mm", "shim" };
if (!nc_file_exists(SHIM_BOOT_COPY_DIR) && !nc_mkdir_p(SHIM_BOOT_COPY_DIR, 0755))
return false;
for (i = 0; i < 3; i++) {
snprintf(path,
PATH_MAX,
"%s/%s" EFI_STUB_SUFFIX_L,
SHIM_BOOT_COPY_DIR,
files[i]);
if (!file_set_text(path, text))
return false;
}
}
#endif /* HAVE_SHIM_SYSTEMD_BOOT */
return true;
}
@@ -449,14 +477,18 @@ int kernel_installed_files_count(BootManager *manager, PlaygroundKernel *kernel)
autofree(char) *kernel_blob_legacy = NULL;
autofree(char) *initrd_file = NULL;
autofree(char) *initrd_file_legacy = NULL;
/* where the kernel files are expected to be found on the ESP */
char *esp_path = manager->bootloader->get_kernel_destination
? manager->bootloader->get_kernel_destination(manager)
: "efi/" KERNEL_NAMESPACE;
const char *vendor = NULL;
int file_count = 0;
vendor = boot_manager_get_vendor_prefix(manager);
kernel_blob = string_printf("%s/efi/%s/kernel-%s.%s.%s-%d",
kernel_blob = string_printf("%s/%s/kernel-%s.%s.%s-%d",
BOOT_FULL,
KERNEL_NAMESPACE,
esp_path,
KERNEL_NAMESPACE,
kernel->ktype,
kernel->version,
@@ -470,9 +502,9 @@ int kernel_installed_files_count(BootManager *manager, PlaygroundKernel *kernel)
kernel->version,
kernel->release);
initrd_file = string_printf("%s/efi/%s/initrd-%s.%s.%s-%d",
initrd_file = string_printf("%s/%s/initrd-%s.%s.%s-%d",
BOOT_FULL,
KERNEL_NAMESPACE,
esp_path,
KERNEL_NAMESPACE,
kernel->ktype,
kernel->version,