From 98e373c9d4c5b5f6530215b9365aece461238a7b Mon Sep 17 00:00:00 2001 From: Siddhant Jajoo Date: Wed, 4 Nov 2020 15:35:40 -0700 Subject: [PATCH 1/5] Adding scripts to align boot and rootfs partition The mender boot slot values are not in sync with nvbootctrl slot values. The values are updated correctly in the mender_boot_part variable, but the nvbootctrl fails to sync up with the latest boot partition to use on the next reboot after a mender update sometimes. This commit would rectify the issue by identifying the mismatch and giving a Warning and dumping all the data for debug. At the same time it would set the active boot partition based on the value in mender_boot_partition, so that there is no mismatch going forward. This script would run after every mender update and will run as a one shot service. --- .../recipes-mender/mender-client/files/mender | 19 +++++++ .../files/mender-client-commit.service | 11 ++++ .../files/mender-client-commit.sh | 11 ++++ .../verify-boot-rootfs-slot-alignment-uboot | 56 +++++++++++++++++++ .../mender-client/mender-client_%.bbappend | 24 ++++++++ 5 files changed, 121 insertions(+) create mode 100644 meta-mender-tegra/recipes-mender/mender-client/files/mender create mode 100644 meta-mender-tegra/recipes-mender/mender-client/files/mender-client-commit.service create mode 100644 meta-mender-tegra/recipes-mender/mender-client/files/mender-client-commit.sh create mode 100644 meta-mender-tegra/recipes-mender/mender-client/files/verify-boot-rootfs-slot-alignment-uboot diff --git a/meta-mender-tegra/recipes-mender/mender-client/files/mender b/meta-mender-tegra/recipes-mender/mender-client/files/mender new file mode 100644 index 00000000..655c88ec --- /dev/null +++ b/meta-mender-tegra/recipes-mender/mender-client/files/mender @@ -0,0 +1,19 @@ +#!/bin/sh + +echo "Starting mender wrapper" + +echo $@ | grep 'install\|-install' > /dev/null +if [ $? -eq 0 ]; then + /etc/mender/verify-boot-rootfs-slot-alignment-uboot || exit 1 +fi + +mender_override $@ + +rc=$? +if [ $rc -eq 0 ]; then + echo $@ | grep 'install\|-install' > /dev/null + if [ $? -eq 0 ]; then + touch /var/lib/mender/mender-install-success + fi +fi + diff --git a/meta-mender-tegra/recipes-mender/mender-client/files/mender-client-commit.service b/meta-mender-tegra/recipes-mender/mender-client/files/mender-client-commit.service new file mode 100644 index 00000000..35087e7d --- /dev/null +++ b/meta-mender-tegra/recipes-mender/mender-client/files/mender-client-commit.service @@ -0,0 +1,11 @@ +[Unit] +Description=Automatic Mender Commit Service +After=mender-client.service + +[Service] +ExecStart=/etc/mender/mender-client-commit.sh +Type=oneshot +StandardOutput=journal+console + +[Install] +WantedBy=multi-user.target diff --git a/meta-mender-tegra/recipes-mender/mender-client/files/mender-client-commit.sh b/meta-mender-tegra/recipes-mender/mender-client/files/mender-client-commit.sh new file mode 100644 index 00000000..fc736146 --- /dev/null +++ b/meta-mender-tegra/recipes-mender/mender-client/files/mender-client-commit.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +/etc/mender/verify-boot-rootfs-slot-alignment-uboot || exit 0 + +if [ -f /var/lib/mender/mender-install-success ]; then + /usr/bin/mender -commit + rc=$? + if [ $rc -eq 0 ]; then + rm /var/lib/mender/mender-install-success + fi +fi diff --git a/meta-mender-tegra/recipes-mender/mender-client/files/verify-boot-rootfs-slot-alignment-uboot b/meta-mender-tegra/recipes-mender/mender-client/files/verify-boot-rootfs-slot-alignment-uboot new file mode 100644 index 00000000..289cd46a --- /dev/null +++ b/meta-mender-tegra/recipes-mender/mender-client/files/verify-boot-rootfs-slot-alignment-uboot @@ -0,0 +1,56 @@ +#!/bin/sh + +echo "Verify if nvbootctrl slot matches rootfs partition" + +# This variable will be populated with the partition number to boot from +mender_boot_partition=`fw_printenv -n mender_boot_part` +devnam=`grep -h "RootfsPart" /etc/mender/mender.conf /var/lib/mender/mender.conf | grep ${mender_boot_partition} | tr -d '" ' | sed "s/RootfsPart//" | cut -f1 -d":"` + +# Fetching corresponding boot slot +if [ $devnam = A ]; then + mender_boot_slot=0 +elif [ $devnam = B ]; then + mender_boot_slot=1 +fi + +# Have default value here in case priorities are equal +nvbootctrl_slot=`nvbootctrl get-current-slot` +priority_slot0=`nvbootctrl dump-slots-info | grep 'priority' | awk 'FNR == 1 {print $4}' | cut -d ',' -f 1` +priority_slot1=`nvbootctrl dump-slots-info | grep 'priority' | awk 'FNR == 2 {print $4}' | cut -d ',' -f 1` + +# Determining the boot slot that would be used after reboot +# Whichever boot slot would have the higher priority, that would be used in the next boot. +if [ $priority_slot1 -gt $priority_slot0 ]; then + nvbootctrl_slot=1 +elif [ $priority_slot0 -gt $priority_slot1 ]; then + nvbootctrl_slot=0 +fi + +# Checking if the mender and nvbootctrl align to the same boot slots +# if not set nvbootctrl active boot slot sane as mender_boot_slot +# Dumping Warning prints to stderr since mender state scripts logs only read stderr. +if [ $mender_boot_slot -ne $nvbootctrl_slot ]; then + echo "********************* WARNING!!!!! *********************" + echo "Partition mismatch for boot and rootfs on reboot" + echo "mender boot slot: ${mender_boot_slot}" + echo "nvbootctrl slot: ${nvbootctrl_slot}" + echo "Setting the current nvbootctrl slot manually to the value of mender boot slot" + nvbootctrl set-active-boot-slot ${mender_boot_slot} + + echo "********************* WARNING!!!!! *********************" + echo "Dumping partition information" + echo `nvbootctrl get-current-slot` + echo `nvbootctrl dump-slots-info` + echo `fw_printenv -n mender_boot_part` + + echo "********************* WARNING!!!!! *********************" + echo "Disabling mender-client systemd service to prevent any more updates" + systemctl stop mender-client + + echo "Reboot the device to set the active slot before proceeding for a mender -install or mender -commit" + exit 1 +else + echo "Verified" +fi + +exit 0 \ No newline at end of file diff --git a/meta-mender-tegra/recipes-mender/mender-client/mender-client_%.bbappend b/meta-mender-tegra/recipes-mender/mender-client/mender-client_%.bbappend index b8aa365f..d6829ef6 100644 --- a/meta-mender-tegra/recipes-mender/mender-client/mender-client_%.bbappend +++ b/meta-mender-tegra/recipes-mender/mender-client/mender-client_%.bbappend @@ -1 +1,25 @@ RDEPENDS_${PN}_append_tegra = "${@' tegra-bup-payload libubootenv-fake' if d.getVar('PREFERRED_PROVIDER_virtual/bootloader').startswith('cboot') else ''}" + +FILESEXTRAPATHS_prepend := "${THISDIR}/files:" +SRC_URI_append_mender-uboot = " \ + file://mender \ + file://mender-client-commit.service \ + file://mender-client-commit.sh \ + file://verify-boot-rootfs-slot-alignment-uboot \ +" + +FILES_${PN}_append_mender-uboot = " ${systemd_system_unitdir}/mender-client-commit.service" +FILES_${PN}_append_mender-uboot = " ${sysconfdir}/mender/mender-client-commit.sh" +FILES_${PN}_append_mender-uboot = " ${bindir}/mender" +FILES_${PN}_append_mender-uboot = " ${sysconfdir}/mender/verify-boot-rootfs-slot-alignment-uboot" + +SYSTEMD_SERVICE_${PN}_append_mender-uboot = " mender-client-commit.service" + +do_install_append_mender-uboot() { + mv ${D}${bindir}/mender ${D}${bindir}/mender_override + install -m 0755 ${WORKDIR}/mender ${D}${bindir}/mender + install -d ${D}${sysconfdir}/mender/scripts + install -m 0755 ${WORKDIR}/mender-client-commit.sh ${D}${sysconfdir}/mender/mender-client-commit.sh + install -m 0644 ${WORKDIR}/mender-client-commit.service ${D}${systemd_system_unitdir}/mender-client-commit.service + install -m 0755 ${WORKDIR}/verify-boot-rootfs-slot-alignment-uboot ${D}${sysconfdir}/mender/verify-boot-rootfs-slot-alignment-uboot +} From 835fe55cb63f6138244a78bbce6f24c38ac62a08 Mon Sep 17 00:00:00 2001 From: Dan Walkes Date: Sat, 7 Nov 2020 08:05:53 -0700 Subject: [PATCH 2/5] Update mender client commit support Move verify boot slot alignment scripts into separate files so we can support the client commit service in non redundant bootloader cases like t210 and cboot cases where no verification is necessary Signed-off-by: Dan Walkes --- .../recipes-mender/mender-client/files/mender | 12 ++-- .../files/mender-client-commit.sh | 2 +- .../verify-boot-rootfs-slot-alignment-cboot | 5 ++ ...tfs-slot-alignment-no-redundant-bootloader | 3 + .../verify-boot-rootfs-slot-alignment-uboot | 2 +- .../mender-client/mender-client_%.bbappend | 57 ++++++++++++++++--- 6 files changed, 67 insertions(+), 14 deletions(-) create mode 100644 meta-mender-tegra/recipes-mender/mender-client/files/verify-boot-rootfs-slot-alignment-cboot create mode 100644 meta-mender-tegra/recipes-mender/mender-client/files/verify-boot-rootfs-slot-alignment-no-redundant-bootloader diff --git a/meta-mender-tegra/recipes-mender/mender-client/files/mender b/meta-mender-tegra/recipes-mender/mender-client/files/mender index 655c88ec..60a45337 100644 --- a/meta-mender-tegra/recipes-mender/mender-client/files/mender +++ b/meta-mender-tegra/recipes-mender/mender-client/files/mender @@ -2,18 +2,22 @@ echo "Starting mender wrapper" -echo $@ | grep 'install\|-install' > /dev/null +# Did the user specify standalone install mode? +echo $@ | grep ' install \| -install ' > /dev/null if [ $? -eq 0 ]; then + install_arg=true + # Exit with failure and error message if we don't have alignment + # between boot slot and rootfs. It's not safe to update in this case /etc/mender/verify-boot-rootfs-slot-alignment-uboot || exit 1 fi +# Call the base mender executable, renamed mender_override $@ rc=$? if [ $rc -eq 0 ]; then - echo $@ | grep 'install\|-install' > /dev/null - if [ $? -eq 0 ]; then + if [ "$install_arg" = true ]; then + # Add a marker to show update was successful, for auto-commit script touch /var/lib/mender/mender-install-success fi fi - diff --git a/meta-mender-tegra/recipes-mender/mender-client/files/mender-client-commit.sh b/meta-mender-tegra/recipes-mender/mender-client/files/mender-client-commit.sh index fc736146..5ca7124f 100644 --- a/meta-mender-tegra/recipes-mender/mender-client/files/mender-client-commit.sh +++ b/meta-mender-tegra/recipes-mender/mender-client/files/mender-client-commit.sh @@ -1,6 +1,6 @@ #!/bin/sh -/etc/mender/verify-boot-rootfs-slot-alignment-uboot || exit 0 +/etc/mender/verify-boot-rootfs-slot-alignment || exit 0 if [ -f /var/lib/mender/mender-install-success ]; then /usr/bin/mender -commit diff --git a/meta-mender-tegra/recipes-mender/mender-client/files/verify-boot-rootfs-slot-alignment-cboot b/meta-mender-tegra/recipes-mender/mender-client/files/verify-boot-rootfs-slot-alignment-cboot new file mode 100644 index 00000000..6ca8c422 --- /dev/null +++ b/meta-mender-tegra/recipes-mender/mender-client/files/verify-boot-rootfs-slot-alignment-cboot @@ -0,0 +1,5 @@ +#!/bin/sh +nvbootctrl_slot=`nvbootctrl get-current-slot` +echo "Current boot slot is ${nvbootctrl_slot}" +echo "Boot slot misalignment is not possible on cboot based tegra platforms" +exit 0 diff --git a/meta-mender-tegra/recipes-mender/mender-client/files/verify-boot-rootfs-slot-alignment-no-redundant-bootloader b/meta-mender-tegra/recipes-mender/mender-client/files/verify-boot-rootfs-slot-alignment-no-redundant-bootloader new file mode 100644 index 00000000..ce0bd516 --- /dev/null +++ b/meta-mender-tegra/recipes-mender/mender-client/files/verify-boot-rootfs-slot-alignment-no-redundant-bootloader @@ -0,0 +1,3 @@ +#!/bin/sh +echo "This tegra platform does not support redundant bootloader" +exit 0 diff --git a/meta-mender-tegra/recipes-mender/mender-client/files/verify-boot-rootfs-slot-alignment-uboot b/meta-mender-tegra/recipes-mender/mender-client/files/verify-boot-rootfs-slot-alignment-uboot index 289cd46a..ab99b9cf 100644 --- a/meta-mender-tegra/recipes-mender/mender-client/files/verify-boot-rootfs-slot-alignment-uboot +++ b/meta-mender-tegra/recipes-mender/mender-client/files/verify-boot-rootfs-slot-alignment-uboot @@ -53,4 +53,4 @@ else echo "Verified" fi -exit 0 \ No newline at end of file +exit 0 diff --git a/meta-mender-tegra/recipes-mender/mender-client/mender-client_%.bbappend b/meta-mender-tegra/recipes-mender/mender-client/mender-client_%.bbappend index d6829ef6..0e158a46 100644 --- a/meta-mender-tegra/recipes-mender/mender-client/mender-client_%.bbappend +++ b/meta-mender-tegra/recipes-mender/mender-client/mender-client_%.bbappend @@ -1,25 +1,66 @@ RDEPENDS_${PN}_append_tegra = "${@' tegra-bup-payload libubootenv-fake' if d.getVar('PREFERRED_PROVIDER_virtual/bootloader').startswith('cboot') else ''}" FILESEXTRAPATHS_prepend := "${THISDIR}/files:" -SRC_URI_append_mender-uboot = " \ +SRC_URI_append = " \ file://mender \ file://mender-client-commit.service \ file://mender-client-commit.sh \ file://verify-boot-rootfs-slot-alignment-uboot \ + file://verify-boot-rootfs-slot-alignment-cboot \ + file://verify-boot-rootfs-slot-alignment-no-redundant-bootloader \ " -FILES_${PN}_append_mender-uboot = " ${systemd_system_unitdir}/mender-client-commit.service" -FILES_${PN}_append_mender-uboot = " ${sysconfdir}/mender/mender-client-commit.sh" -FILES_${PN}_append_mender-uboot = " ${bindir}/mender" -FILES_${PN}_append_mender-uboot = " ${sysconfdir}/mender/verify-boot-rootfs-slot-alignment-uboot" +FILES_${PN} += " \ + ${systemd_system_unitdir}/mender-client-commit.service \ + ${sysconfdir}/mender/mender-client-commit.sh \ + ${bindir}/mender_base \ + ${sysconfdir}/mender/verify-boot-rootfs-slot-alignment \ +" -SYSTEMD_SERVICE_${PN}_append_mender-uboot = " mender-client-commit.service" +SYSTEMD_SERVICE_${PN} += "mender-client-commit.service" -do_install_append_mender-uboot() { +install_commit_service() { + # Rename the mender binary as mender_override. We'll override with a script that records how it's used mv ${D}${bindir}/mender ${D}${bindir}/mender_override install -m 0755 ${WORKDIR}/mender ${D}${bindir}/mender install -d ${D}${sysconfdir}/mender/scripts install -m 0755 ${WORKDIR}/mender-client-commit.sh ${D}${sysconfdir}/mender/mender-client-commit.sh install -m 0644 ${WORKDIR}/mender-client-commit.service ${D}${systemd_system_unitdir}/mender-client-commit.service - install -m 0755 ${WORKDIR}/verify-boot-rootfs-slot-alignment-uboot ${D}${sysconfdir}/mender/verify-boot-rootfs-slot-alignment-uboot } + +# By default, install the cboot version of the slot alignment verify script +install_slot_align_verify() { + install -m 0755 ${WORKDIR}/verify-boot-rootfs-slot-alignment-cboot ${D}${sysconfdir}/mender/verify-boot-rootfs-slot-alignment +} + + +# When mender-uboot override is defined, install the u-boot version. This one is important for ensuring slots are aligned +# between uboot and the rootfs before taking actions like update +install_slot_align_verify_mender-uboot() { + install -m 0755 ${WORKDIR}/verify-boot-rootfs-slot-alignment-uboot ${D}${sysconfdir}/mender/verify-boot-rootfs-slot-alignment +} + +# This verify script is a no-op, since there's nothing to do if redundant bootloader is not supported +install_slot_align_verify_no_redundant_bootloader() { + install -m 0755 ${WORKDIR}/verify-boot-rootfs-slot-alignment-no-redundant-bootloader ${D}${sysconfdir}/mender/verify-boot-rootfs-slot-alignment +} + +# Tegra 210 (nano) platforms don't support redundant bootloader today +# Use the version of the slot alignment verify script which doesn't use redundant bootloader +do_install_append_tegra210() { + install_commit_service + install_slot_align_verify_no_redundant_bootloader +} + +do_install_append_tegra194() { + install_commit_service + install_slot_align_verify +} + +do_install_append_tegra186() { + install_commit_service + # If building the uboot build, the slot alignment verify script will be installed by override here + install_slot_align_verify +} + +PACKAGE_ARCH = "${MACHINE_ARCH}" From 0c16daef03dd15704b9c2942ee573496b21c6593 Mon Sep 17 00:00:00 2001 From: Dan Walkes Date: Sat, 7 Nov 2020 15:07:50 -0700 Subject: [PATCH 3/5] Handful of Fixes * Use correct quoting on echo arguments so match succeeds * Move verify script into bin dir, rename with mender-tegra prefix --- .../recipes-mender/mender-client/files/mender | 6 ++++-- .../files/mender-client-commit.service | 2 +- .../files/mender-client-commit.sh | 2 +- ...ra-verify-boot-rootfs-slot-alignment-cboot} | 0 ...tfs-slot-alignment-no-redundant-bootloader} | 0 ...ra-verify-boot-rootfs-slot-alignment-uboot} | 0 .../mender-client/mender-client_%.bbappend | 18 +++++++++--------- 7 files changed, 15 insertions(+), 13 deletions(-) rename meta-mender-tegra/recipes-mender/mender-client/files/{verify-boot-rootfs-slot-alignment-cboot => mender-tegra-verify-boot-rootfs-slot-alignment-cboot} (100%) rename meta-mender-tegra/recipes-mender/mender-client/files/{verify-boot-rootfs-slot-alignment-no-redundant-bootloader => mender-tegra-verify-boot-rootfs-slot-alignment-no-redundant-bootloader} (100%) rename meta-mender-tegra/recipes-mender/mender-client/files/{verify-boot-rootfs-slot-alignment-uboot => mender-tegra-verify-boot-rootfs-slot-alignment-uboot} (100%) diff --git a/meta-mender-tegra/recipes-mender/mender-client/files/mender b/meta-mender-tegra/recipes-mender/mender-client/files/mender index 60a45337..97b979c6 100644 --- a/meta-mender-tegra/recipes-mender/mender-client/files/mender +++ b/meta-mender-tegra/recipes-mender/mender-client/files/mender @@ -3,12 +3,13 @@ echo "Starting mender wrapper" # Did the user specify standalone install mode? -echo $@ | grep ' install \| -install ' > /dev/null +echo " $@" | grep ' install \| -install ' > /dev/null if [ $? -eq 0 ]; then + echo "Detected install arg for standalone install mode" install_arg=true # Exit with failure and error message if we don't have alignment # between boot slot and rootfs. It's not safe to update in this case - /etc/mender/verify-boot-rootfs-slot-alignment-uboot || exit 1 + mender-tegra-verify-boot-rootfs-slot-alignment || exit 1 fi # Call the base mender executable, renamed @@ -17,6 +18,7 @@ mender_override $@ rc=$? if [ $rc -eq 0 ]; then if [ "$install_arg" = true ]; then + echo "Adding marker file to show standalone install was successful" # Add a marker to show update was successful, for auto-commit script touch /var/lib/mender/mender-install-success fi diff --git a/meta-mender-tegra/recipes-mender/mender-client/files/mender-client-commit.service b/meta-mender-tegra/recipes-mender/mender-client/files/mender-client-commit.service index 35087e7d..948f33af 100644 --- a/meta-mender-tegra/recipes-mender/mender-client/files/mender-client-commit.service +++ b/meta-mender-tegra/recipes-mender/mender-client/files/mender-client-commit.service @@ -3,7 +3,7 @@ Description=Automatic Mender Commit Service After=mender-client.service [Service] -ExecStart=/etc/mender/mender-client-commit.sh +ExecStart=/usr/bin/mender-client-commit.sh Type=oneshot StandardOutput=journal+console diff --git a/meta-mender-tegra/recipes-mender/mender-client/files/mender-client-commit.sh b/meta-mender-tegra/recipes-mender/mender-client/files/mender-client-commit.sh index 5ca7124f..7270ced6 100644 --- a/meta-mender-tegra/recipes-mender/mender-client/files/mender-client-commit.sh +++ b/meta-mender-tegra/recipes-mender/mender-client/files/mender-client-commit.sh @@ -1,6 +1,6 @@ #!/bin/sh -/etc/mender/verify-boot-rootfs-slot-alignment || exit 0 +mender-tegra-verify-boot-rootfs-slot-alignment || exit 0 if [ -f /var/lib/mender/mender-install-success ]; then /usr/bin/mender -commit diff --git a/meta-mender-tegra/recipes-mender/mender-client/files/verify-boot-rootfs-slot-alignment-cboot b/meta-mender-tegra/recipes-mender/mender-client/files/mender-tegra-verify-boot-rootfs-slot-alignment-cboot similarity index 100% rename from meta-mender-tegra/recipes-mender/mender-client/files/verify-boot-rootfs-slot-alignment-cboot rename to meta-mender-tegra/recipes-mender/mender-client/files/mender-tegra-verify-boot-rootfs-slot-alignment-cboot diff --git a/meta-mender-tegra/recipes-mender/mender-client/files/verify-boot-rootfs-slot-alignment-no-redundant-bootloader b/meta-mender-tegra/recipes-mender/mender-client/files/mender-tegra-verify-boot-rootfs-slot-alignment-no-redundant-bootloader similarity index 100% rename from meta-mender-tegra/recipes-mender/mender-client/files/verify-boot-rootfs-slot-alignment-no-redundant-bootloader rename to meta-mender-tegra/recipes-mender/mender-client/files/mender-tegra-verify-boot-rootfs-slot-alignment-no-redundant-bootloader diff --git a/meta-mender-tegra/recipes-mender/mender-client/files/verify-boot-rootfs-slot-alignment-uboot b/meta-mender-tegra/recipes-mender/mender-client/files/mender-tegra-verify-boot-rootfs-slot-alignment-uboot similarity index 100% rename from meta-mender-tegra/recipes-mender/mender-client/files/verify-boot-rootfs-slot-alignment-uboot rename to meta-mender-tegra/recipes-mender/mender-client/files/mender-tegra-verify-boot-rootfs-slot-alignment-uboot diff --git a/meta-mender-tegra/recipes-mender/mender-client/mender-client_%.bbappend b/meta-mender-tegra/recipes-mender/mender-client/mender-client_%.bbappend index 0e158a46..393cb061 100644 --- a/meta-mender-tegra/recipes-mender/mender-client/mender-client_%.bbappend +++ b/meta-mender-tegra/recipes-mender/mender-client/mender-client_%.bbappend @@ -5,16 +5,16 @@ SRC_URI_append = " \ file://mender \ file://mender-client-commit.service \ file://mender-client-commit.sh \ - file://verify-boot-rootfs-slot-alignment-uboot \ - file://verify-boot-rootfs-slot-alignment-cboot \ - file://verify-boot-rootfs-slot-alignment-no-redundant-bootloader \ + file://mender-tegra-verify-boot-rootfs-slot-alignment-uboot \ + file://mender-tegra-verify-boot-rootfs-slot-alignment-cboot \ + file://mender-tegra-verify-boot-rootfs-slot-alignment-no-redundant-bootloader \ " FILES_${PN} += " \ ${systemd_system_unitdir}/mender-client-commit.service \ - ${sysconfdir}/mender/mender-client-commit.sh \ + ${bindir}/mender-client-commit.sh \ ${bindir}/mender_base \ - ${sysconfdir}/mender/verify-boot-rootfs-slot-alignment \ + ${bindir}/mender-tegra-verify-boot-rootfs-slot-alignment \ " SYSTEMD_SERVICE_${PN} += "mender-client-commit.service" @@ -24,25 +24,25 @@ install_commit_service() { mv ${D}${bindir}/mender ${D}${bindir}/mender_override install -m 0755 ${WORKDIR}/mender ${D}${bindir}/mender install -d ${D}${sysconfdir}/mender/scripts - install -m 0755 ${WORKDIR}/mender-client-commit.sh ${D}${sysconfdir}/mender/mender-client-commit.sh + install -m 0755 ${WORKDIR}/mender-client-commit.sh ${D}${bindir}/mender-client-commit.sh install -m 0644 ${WORKDIR}/mender-client-commit.service ${D}${systemd_system_unitdir}/mender-client-commit.service } # By default, install the cboot version of the slot alignment verify script install_slot_align_verify() { - install -m 0755 ${WORKDIR}/verify-boot-rootfs-slot-alignment-cboot ${D}${sysconfdir}/mender/verify-boot-rootfs-slot-alignment + install -m 0755 ${WORKDIR}/mender-tegra-verify-boot-rootfs-slot-alignment-cboot ${D}${bindir}/mender-tegra-verify-boot-rootfs-slot-alignment } # When mender-uboot override is defined, install the u-boot version. This one is important for ensuring slots are aligned # between uboot and the rootfs before taking actions like update install_slot_align_verify_mender-uboot() { - install -m 0755 ${WORKDIR}/verify-boot-rootfs-slot-alignment-uboot ${D}${sysconfdir}/mender/verify-boot-rootfs-slot-alignment + install -m 0755 ${WORKDIR}/mender-tegra-verify-boot-rootfs-slot-alignment-uboot ${D}${bindir}/mender-tegra-verify-boot-rootfs-slot-alignment } # This verify script is a no-op, since there's nothing to do if redundant bootloader is not supported install_slot_align_verify_no_redundant_bootloader() { - install -m 0755 ${WORKDIR}/verify-boot-rootfs-slot-alignment-no-redundant-bootloader ${D}${sysconfdir}/mender/verify-boot-rootfs-slot-alignment + install -m 0755 ${WORKDIR}/mender-tegra-verify-boot-rootfs-slot-alignment-no-redundant-bootloader ${D}${bindir}/mender-tegra-verify-boot-rootfs-slot-alignment } # Tegra 210 (nano) platforms don't support redundant bootloader today From bb796b03c094e626570341475e7d044c2388e399 Mon Sep 17 00:00:00 2001 From: Dan Walkes Date: Sat, 7 Nov 2020 16:20:07 -0700 Subject: [PATCH 4/5] Prevent install from mender install on boot slot mismatch When boot slots aren't aligned (as detected/corrected by the verify alignment script) we need to set a marker file in the volatile FS to prevent future mender -install attempts from running until the next reboot when boot slots are once again aligned. --- meta-mender-tegra/recipes-mender/mender-client/files/mender | 5 +++++ .../mender-tegra-verify-boot-rootfs-slot-alignment-uboot | 2 ++ 2 files changed, 7 insertions(+) diff --git a/meta-mender-tegra/recipes-mender/mender-client/files/mender b/meta-mender-tegra/recipes-mender/mender-client/files/mender index 97b979c6..faba1e37 100644 --- a/meta-mender-tegra/recipes-mender/mender-client/files/mender +++ b/meta-mender-tegra/recipes-mender/mender-client/files/mender @@ -10,6 +10,11 @@ if [ $? -eq 0 ]; then # Exit with failure and error message if we don't have alignment # between boot slot and rootfs. It's not safe to update in this case mender-tegra-verify-boot-rootfs-slot-alignment || exit 1 + if [ -e /var/volatile/mender-tegra-boot-slot-mismatch-install-disabled ]; then + echo "Disabling mender -install since a boot slot mismatch was detected." + echo "please reboot to realign boot slots" + exit 1 + fi fi # Call the base mender executable, renamed diff --git a/meta-mender-tegra/recipes-mender/mender-client/files/mender-tegra-verify-boot-rootfs-slot-alignment-uboot b/meta-mender-tegra/recipes-mender/mender-client/files/mender-tegra-verify-boot-rootfs-slot-alignment-uboot index ab99b9cf..cad10eea 100644 --- a/meta-mender-tegra/recipes-mender/mender-client/files/mender-tegra-verify-boot-rootfs-slot-alignment-uboot +++ b/meta-mender-tegra/recipes-mender/mender-client/files/mender-tegra-verify-boot-rootfs-slot-alignment-uboot @@ -47,6 +47,8 @@ if [ $mender_boot_slot -ne $nvbootctrl_slot ]; then echo "Disabling mender-client systemd service to prevent any more updates" systemctl stop mender-client + # Create a marker file to prevent mender-install from running + touch /var/volatile/mender-tegra-boot-slot-mismatch-install-disabled echo "Reboot the device to set the active slot before proceeding for a mender -install or mender -commit" exit 1 else From 967625a3d7f7e6135267933da729e0c4086e18fb Mon Sep 17 00:00:00 2001 From: Dan Walkes Date: Tue, 10 Nov 2020 18:24:55 -0700 Subject: [PATCH 5/5] Add mender test script --- scripts/mender_tegra_tests.py | 156 ++++++++++++++++++++++++++++++++++ scripts/requirements.txt | 1 + 2 files changed, 157 insertions(+) create mode 100644 scripts/mender_tegra_tests.py create mode 100644 scripts/requirements.txt diff --git a/scripts/mender_tegra_tests.py b/scripts/mender_tegra_tests.py new file mode 100644 index 00000000..8dc31ddf --- /dev/null +++ b/scripts/mender_tegra_tests.py @@ -0,0 +1,156 @@ +import fabric2 +from fabric2 import Connection +import argparse +import time +import traceback +import sys +import re +import subprocess +import platform + +class MenderStandaloneTests: + DEFAULT_USER = 'root' + args = None + connection = None + argparser = None + + def get_parser(self): + if self.argparser is None: + ''' + Argument parsing for new deployment and provisioning process + ''' + argparser = argparse.ArgumentParser(prog='mender_tegra_tests.py', + usage='%(prog)s [options]', + description='Provisions Boulder AI devices') + argparser.add_argument('-d', + '--device', + help='The IP address or name of the device') + + argparser.add_argument('-u', + '--user', + help="The SSH username (default is {})".format(self.DEFAULT_USER)) + + argparser.add_argument('-p', + '--password', + help='The SSH password (default is no password)') + + argparser.add_argument('-k', + '--key', + help='The SSH key file (used instead of password if specified)') + + argparser.add_argument('-i', + '--install', + help='The mender install argument to use with standalone install' + + ' (http://mylocalserver:8000/path/to/mender/file') + self.argparser = argparser + return self.argparser + + + def get_args(self): + if self.args is None: + self.args = self.get_parser().parse_args() + + if self.args.user is None: + print("No user specified, using {}".format(self.DEFAULT_USER)) + self.args.user=self.DEFAULT_USER + return self.args + + def get_connection(self): + args = self.get_args() + if self.connection is None: + if args.key is not None: + self.connection = Connection( + host='{}@{}'.format(args.user, args.device), + connect_kwargs={ + "key_filename": args.key, + "password": args.password + }) + elif args.password is not None: + self.connection = Connection( + host='{}@{}'.format(args.user, args.device), + connect_kwargs={ + "password": args.password + }) + else: + self.connection = Connection( + host='{}@{}'.format(args.user, args.device), + connect_kwargs={ + "password": "", + "look_for_keys": False + }) + return self.connection + + def wait_for_device(self): + conn = self.get_connection() + print('Trying to connect to {}....'.format(self.get_args().device)) + success = False + while not success: + try: + conn.open() + success = True + except Exception as e: + print('Exception connecting, retrying in 3 seconds..') + print(e) + traceback.print_exc(file=sys.stdout) + time.sleep(3) + + def ping(self): + args=self.get_args() + """ + Returns True if host (str) responds to a ping request. + Remember that a host may not respond to a ping (ICMP) request even if the host name is valid. + See https://stackoverflow.com/a/32684938/1446624 + """ + + # Option for the number of packets as a function of + param = '-n' if platform.system().lower() == 'windows' else '-c' + + # Building the command. Ex: "ping -c 1 google.com" + command = ['ping', param, '1', args.device] + + return subprocess.call(command) == 0 + + def wait_for_device_removal(self): + while self.ping(): + pass + + def mender_install(self): + args = self.get_args() + conn = self.get_connection() + if args.install is None: + self.get_parser().print_help() + print("Missing argument install") + raise RuntimeError("Missing argument install") + result = conn.run("mender -install {}".format(args.install)) + # Mender doesn't return error states, so we can't check return codes here + match = re.search(r' level=error ', result.stderr, re.MULTILINE) + if match is not None: + raise RuntimeError("Mender install failed with error messages in the logs") + + def mender_commit(self): + self.get_connection().run("mender -commit") + + def reboot(self): + conn = self.get_connection() + print("Rebooting device") + result = conn.run("reboot", warn=True) + self.wait_for_device_removal() + self.wait_for_device() + + def do_single_mender_update(self): + self.wait_for_device() + self.mender_install() + self.reboot() + self.mender_commit() + + + def do_test(self): + self.do_single_mender_update() + + + +if __name__ == '__main__': + test = MenderStandaloneTests() + test.do_test() + + diff --git a/scripts/requirements.txt b/scripts/requirements.txt new file mode 100644 index 00000000..a9e5175e --- /dev/null +++ b/scripts/requirements.txt @@ -0,0 +1 @@ +fabric2>=2.5.0 \ No newline at end of file