Jump to content

LanMarc77

Members
  • Posts

    5
  • Joined

  • Last visited

  1. Ah yes indeed. I meant laibsch. Sorry. I made an autoRevert.sh POC that hooks into the initramfs system. Assuming the partition layout described above the following script will revert to the other partition. It is assumed that if an update happened the updater will place a testBoot1 file inside the new boot directory and reboots. During initrd time the script will check for that file and rename it to testBoot2. If the script already detects a testBoot2 it will change the symlink of /boot to the other partition and reboots. Otherwise it is assumed that once the system is up testBoot2 is deleted from the running system if everything works. The script needs to be placed into /etc/initramfs-tools/scripts/init-premount/ and busybox needs to be installed as the script needs the more sophisticated basic commands. Then rebuild initrd. #!/bin/sh PREREQ="" prereqs() { echo "$PREREQ" if ! dpkg -s busybox>/dev/null 2>&1; then >&2 echo "Busybox not installed." exit 1 fi } case $1 in prereqs) prereqs exit 0 ;; esac reboot=0 echo mkdir /run/bootRevert mount /dev/mmcblk0p1 /run/bootRevert if [ -L "/run/bootRevert/boot" ]; then echo "/boot is a symlink. OK." cd /run/bootRevert currentTarget=$(readlink "boot") if [ -f "boot/testBoot2" ]; then echo -n "Reverting " if [ $currentTarget = "bootA" ]; then echo "to bootB." if [ -f "bootB/armbianEnv.txt" ]; then rm boot/testBoot2 ln -snf bootB boot reboot=1 else echo "Aborting revert. bootB seems to be empty." fi fi if [ $currentTarget = "bootB" ]; then echo "to bootA." if [ -f "bootA/armbianEnv.txt" ]; then rm boot/testBoot2 ln -snf bootA boot reboot=1 else echo "Aborting revert. bootA seems to be empty." fi fi else if [ -f "boot/testBoot1" ]; then echo "Going to testboot stage 2." mv boot/testBoot1 boot/testBoot2 else echo "No revert/testboot detected. Booting $currentTarget normally." fi fi fi cd / umount /run/bootRevert if [ $reboot = "1" ]; then sync echo "Rebooting..." reboot -f fi It seems then this concept works. As the script checks if /boot in the boot partition is a symlink and then does nothing if not it can also be placed in an unchanged armbian system without interfering. Perfect for creating new images. Still missing are the management scripts for: - converting an initially downloaded armbian image into an AB boot partition scheme - creating an image/update package from a running and well prepared or updated local armbian installation - a cronable management script to call a more specific download script and for switching partitions and rebooting - the download script that will attach to any distribution system that downloads the new update package places it into the other partition and adjusts machine identity; this download script could also just implement a backup of the running partition to the other partition so that switching back is possible if OTA is done using apt All of these can be done in shell.
  2. Thinking about a better automated option to revert (e.g. just power off like @The Tall Man suggested) while still not touching uboot or even lower level layers the initrd might be an option based on the current setup. I assume we have very little probability for kernel+initrd load problems. Most issues will probably occur after the rootfs was mounted and handover. Integrating additional scripts inside the initrd could be used to auto revert the symlink in case of failure. Before we are going to reboot we place a status file inside the boot partitions boot directory that we just updated. For this first reboot we call this testboot1. When the new system boots up initrd script checks for this file and renames it to testboot2. If the system boots up correctly or can be accessed remotely /boot/testboot2 is deleted. But if the initrd script sees a testboot2 file during its boot process it knows something went wrong. It then changes the /boot symlink to the other boot folder deletes testboot2 and reboots instead of handing over to the rootfs. If the new system got stuck after it handed over to the rootfs the initrd script should have renamed the file to testboot2 already and a hard restart should revert. This hard reset could probably also be fully automated if the SBC has a hardware watchdog. If the watchdog module is integrated in the initrd it could set it to a reasonable value. The watchdog is then only disabled or changed to normal operation once the system is reliable working or if disabled via remote access. This concept would build on top of what exist. Any community member could choose to test the idea and implement management scripts. I guess everything can be done in bash/sh. It could also lead to a new armbian package: simpleAB which is not perfect but might be enough for many. It would not need many uboot or architectural changes. I guess it also works for all armbian supported devices? But as @Igor already said. One needs to invest.
  3. Thanks @eselarm for the input that this should work. So I tested it. And it does! I leave a few hints for anyone who wants to replicate. When creating a new image layout working directly with the image files was the fastest for me. So you need to download one original Armbian image. I used a minimal cli image. Image preparations Create a new image file (e.g. with dd) that will be partitioned like described above. Copy all the first sectors until the first partition starts from the original image to the new image. This will copy the original partition table but more importantly also the uboot bootloader into the new image (32768 sectors = 16MB). Partitioning Partition the new image as described above (e.g. with fdisk/sfdisk) and format the new partitions. One smaller boot partition (e.g. 512MB, ext4) and two bigger root partitions (e.g. 3GB, ext4). I will use the terms rootA and rootB for the two new root partitions in the new image from here on. Get the UUIDs of the newly created boot and rootA partition of the new image (e.g. lsblk/blkid). Most likely instead of using two separate ext4 rootA and rootB partitions one bigger btrfs partition and the usage of subvolumes could be possible. But I did not test this. Copy boot and adjust Mount the new boot partition and create directories bootA and bootB and a relative symlink boot pointing to bootA. Place all files from the original image’s /boot directory into bootA of the new image. Adjust the UUID line in armbianEnv.txt that still points to the original image’s root partition to the rootA UUID from the new image. Copy root and adjust Mount rootA and copy all the files from the original image into it. Remove all files from the /boot directory in rootA as we will mount the boot partition into this directory anyway and do not want to get mixed up. Create a new directory /rawBoot in rootA. Edit the fstab of rootA and change the UUID that still points to the original image’s root partition to the rootA UUID. Add a line to fstab to mount the boot partition of the new image into /rawBoot. Add a line to fstab to bind mount the directory /boot of /rawBoot into /boot of rootA. Add an empty file /root/.no_rootfs_resize in rootA to avoid the partitions being changed if the original image was never booted before. I did all of the above also with an archived older Armbian image and put that into rootB (and bootB). With this setup we now have two separated OS versions. They can be switched by simply changing the boot symlink to bootA or bootB and reboot. Because we used bind mount we can also do kernel upgrades which end up in the correct directory. As all of the steps are easily automatable by a shell script we can now download a new earlier prepared update package place its content into the other boot directory and partition adjust their UUIDs (and maybe copy SSH keys and machine-id if we want to keep system identity) and change a symlink. If we need to go back to the older image just the symlink needs to changed back. Either from within a running system or if that is not possible by taking the card out and doing this externally. As I said earlier this A+B update scheme is not as robust as other tools. But we can stay with prebuilt images from Armbian that can be locally configured the way we want it. After this an update package can be created and distributed which could also contain a new uboot. If this is tested well before distribution I guess most errors that make the other tools so robust can be avoided.
  4. So am I reading correctly from your post that separating boot and rootfs using armbianEnv.txt does work? Do you think the hardlink option inside the boot partition could work? I would most likely test this setup but would like to know before if there are issues why it never would work to avoid work, I know there are many other options including an initramfs with btrfs support to avoid partitions for different rootfs to then use subvolumes. Still I would like to stick for the time being with the original idea. Thanks.
  5. Getting into buildroot and yocto seems a bit too much for me to get an A+B style update possibility. I would like to stick with the quality images provided by Armbian. The following applies to a NanoPi-NEO3 others SBC might have different partition layouts. From what I understood is that uboot looks for /boot in /dev/mmcblk0p1 reads the boot.cmd/scr and armbianEnv.txt and then boots the kernel accordingly. The armbianEnv.txt seems to point the kernel to the root partition using the rootdev directive. If /dev/mmcblk0p1 would now only hold /boot would it be possible to point to a different partition for the rootfs using armbianEnv.txt? If so I could imagine changing the partition layout to the following: /dev/mmcblk0: /dev/mmcblk0p1: boot partition /dev/mmcblk0p2: rootfs partitionA /dev/mmcblk0p3: rootfs partitionB /dev/mmcblk0pX: multiple more partitions that survive updates Too now allow consistency with the rootfs partitions also the boot partition directory structure would slightly change. It would contain 2 directories: /bootA, /bootB AND a hardlink /boot which either points to /bootA or /bootB In the running rootfs the fitting /boot is mounted via a bind mount hoping normal apt-get updates can deal with this. This would allow creating a rootfs by updating and verifying everything works locally and then creating an image from it. Now to OTA a relatively simple script running from rootfsA can download a new rootfs image/file structure and place it in the partition of rootfsB. Same with the new boot partition just into /bootB. The values of the armbianEnv.txt from the new boot image always point to the corresponding rootfs partition either because the image was already built for this or the script dynamically adjusts them. Same goes for fstab, machine-id, ssh identity and other rootfs specifics. The script will then verify that the write worked to avoid sd card issues. The (almost) atomic operation for switching the systems would be changing the hardlink of /boot to the /bootB directory and reboot. This idea will not detect any boot issues and revert automatically back as uboot is not involved. Also this only works if uboot is still compatible with the new boot files provided. But an additional new uboot image could also be provided during the update. Reverting can be done manually (relatively fast) by changing the hardlink back and rewriting a previously created backup copy of a might be updated uboot image. Independent of the fact that buildroot, yocto, rauc, mender… systems have a better feature set, do you think this could work?
×
×
  • Create New...

Important Information

Terms of Use - Privacy Policy - Guidelines