Add SD card duplicator service to ARM host image
This service is specifically used when writing to
secondary storage (such as an SD card). The SD
card can then be used as a failsafe mechanism to
recover any devices that are stuck in U-Boot and
fail to boot into the kernel. This service will
automatically replicate the disk's contents onto
the primary storage, blink LEDs while doing so,
then hold a constant red LED when done.
BUG: 141692755
Test: local build and run on rock pi 4b
Change-Id: I9fdbb3689c84fa9f31aa3414855ba14b6e53269b
diff --git a/tools/create_base_image_arm.sh b/tools/create_base_image_arm.sh
index 29b24d3..9ecaf44 100755
--- a/tools/create_base_image_arm.sh
+++ b/tools/create_base_image_arm.sh
@@ -176,6 +176,149 @@
git clone https://github.com/google/android-cuttlefish.git
cd -
+echo "Creating led script..."
+cat > ${mntdir}/usr/local/bin/led << "EOF"
+#!/bin/bash
+
+if [ "$1" == "--start" ]; then
+ echo 125 > /sys/class/gpio/export
+ echo out > /sys/class/gpio/gpio125/direction
+ chmod 666 /sys/class/gpio/gpio125/value
+ echo 0 > /sys/class/gpio/gpio125/value
+ exit 0
+fi
+
+if [ "$1" == "--stop" ]; then
+ echo 0 > /sys/class/gpio/gpio125/value
+ echo 125 > /sys/class/gpio/unexport
+ exit 0
+fi
+
+if [ ! -e /sys/class/gpio/gpio125/value ]; then
+ echo "error: led service not initialized"
+ exit 1
+fi
+
+if [ "$1" == "0" ] || [ "$1" == "off" ] || [ "$1" == "OFF" ]; then
+ echo 0 > /sys/class/gpio/gpio125/value
+ exit 0
+fi
+
+if [ "$1" == "1" ] || [ "$1" == "on" ] || [ "$1" == "ON" ]; then
+ echo 1 > /sys/class/gpio/gpio125/value
+ exit 0
+fi
+
+echo "usage: led <0|1>"
+exit 1
+EOF
+chown root:root ${mntdir}/usr/local/bin/led
+chmod 755 ${mntdir}/usr/local/bin/led
+
+echo "Creating led service..."
+cat > ${mntdir}/etc/systemd/system/led.service << EOF
+[Unit]
+ Description=led service
+ ConditionPathExists=/usr/local/bin/led
+
+[Service]
+ Type=oneshot
+ ExecStart=/usr/local/bin/led --start
+ ExecStop=/usr/local/bin/led --stop
+ RemainAfterExit=true
+ StandardOutput=journal
+
+[Install]
+ WantedBy=multi-user.target
+EOF
+
+echo "Creating SD duplicator script..."
+cat > ${mntdir}/usr/local/bin/sd-dupe << "EOF"
+#!/bin/bash
+led 0
+
+src_dev=mmcblk0
+dest_dev=mmcblk1
+part_num=p5
+
+if [ -e /dev/mmcblk0p5 ]; then
+ led 1
+
+ sgdisk -Z -a1 /dev/${dest_dev}
+ sgdisk -a1 -n:1:64:8127 -t:1:8301 -c:1:loader1 /dev/${dest_dev}
+ sgdisk -a1 -n:2:8128:8191 -t:2:8301 -c:2:env /dev/${dest_dev}
+ sgdisk -a1 -n:3:16384:24575 -t:3:8301 -c:3:loader2 /dev/${dest_dev}
+ sgdisk -a1 -n:4:24576:32767 -t:4:8301 -c:4:trust /dev/${dest_dev}
+ sgdisk -a1 -n:5:32768:- -A:5:set:2 -t:5:8305 -c:5:rootfs /dev/${dest_dev}
+
+ src_block_count=`tune2fs -l /dev/${src_dev}${part_num} | grep "Block count:" | sed 's/.*: *//'`
+ src_block_size=`tune2fs -l /dev/${src_dev}${part_num} | grep "Block size:" | sed 's/.*: *//'`
+ src_fs_size=$(( src_block_count*src_block_size ))
+ src_fs_size_m=$(( src_fs_size / 1024 / 1024 + 1 ))
+
+ dd if=/dev/${src_dev}p1 of=/dev/${dest_dev}p1 conv=sync,noerror status=progress
+ dd if=/dev/${src_dev}p2 of=/dev/${dest_dev}p2 conv=sync,noerror status=progress
+ dd if=/dev/${src_dev}p3 of=/dev/${dest_dev}p3 conv=sync,noerror status=progress
+ dd if=/dev/${src_dev}p4 of=/dev/${dest_dev}p4 conv=sync,noerror status=progress
+
+ echo "Writing ${src_fs_size_m} MB: /dev/${src_dev} -> /dev/${dest_dev}..."
+ dd if=/dev/${src_dev}${part_num} of=/dev/${dest_dev}${part_num} bs=1M conv=sync,noerror status=progress
+
+ echo "Expanding /dev/${dest_dev}${part_num} filesystem..."
+ e2fsck -fy /dev/${dest_dev}${part_num}
+ resize2fs /dev/${dest_dev}${part_num}
+ tune2fs -O has_journal /dev/${dest_dev}${part_num}
+ e2fsck -fy /dev/${dest_dev}${part_num}
+ sync /dev/${dest_dev}
+
+ echo "Cleaning up..."
+ mount /dev/${dest_dev}${part_num} /media
+ chroot /media /usr/local/bin/install-cleanup
+
+ if [ $? == 0 ]; then
+ echo "Successfully copied Rock Pi image!"
+ while true; do
+ led 1; sleep 0.5
+ led 0; sleep 0.5
+ done
+ else
+ echo "Error while copying Rock Pi image"
+ while true; do
+ led 1; sleep 0.1
+ led 0; sleep 0.1
+ done
+ fi
+else
+ echo "Expanding /dev/${dest_dev}${part_num} filesystem..."
+ e2fsck -fy /dev/${dest_dev}${part_num}
+ resize2fs /dev/${dest_dev}${part_num}
+ tune2fs -O has_journal /dev/${dest_dev}${part_num}
+ e2fsck -fy /dev/${dest_dev}${part_num}
+ sync /dev/${dest_dev}
+
+ echo "Cleaning up..."
+ /usr/local/bin/install-cleanup
+fi
+EOF
+chmod +x ${mntdir}/usr/local/bin/sd-dupe
+
+echo "Creating SD duplicator service..."
+cat > ${mntdir}/etc/systemd/system/sd-dupe.service << EOF
+[Unit]
+ Description=Duplicate SD card rootfs to eMMC on Rock Pi
+ ConditionPathExists=/usr/local/bin/sd-dupe
+ After=led.service
+
+[Service]
+ Type=simple
+ ExecStart=/usr/local/bin/sd-dupe
+ TimeoutSec=0
+ StandardOutput=tty
+
+[Install]
+ WantedBy=multi-user.target
+EOF
+
echo "Creating cleanup script..."
cat > ${mntdir}/usr/local/bin/install-cleanup << "EOF"
#!/bin/bash
@@ -200,7 +343,6 @@
apt-get install -y -f ../cuttlefish-common_*_arm64.deb
apt-get clean
usermod -aG cvdnetwork vsoc-01
-chown -R vsoc-01:vsoc-01 /home/vsoc-01
chmod 660 /dev/vhost-vsock
chown root:cvdnetwork /dev/vhost-vsock
@@ -209,30 +351,17 @@
dbus-uuidgen --ensure
systemd-machine-id-setup
-systemctl disable cleanup
+systemctl disable sd-dupe
+rm /etc/systemd/system/sd-dupe.service
+rm /usr/local/bin/sd-dupe
rm /usr/local/bin/install-cleanup
EOF
chmod +x ${mntdir}/usr/local/bin/install-cleanup
-echo "Creating cleanup service..."
-cat > ${mntdir}/etc/systemd/system/cleanup.service << EOF
-[Unit]
- Description=cleanup service
- ConditionPathExists=/usr/local/bin/install-cleanup
-
-[Service]
- Type=simple
- ExecStart=/usr/local/bin/install-cleanup
- TimeoutSec=0
- StandardOutput=tty
-
-[Install]
- WantedBy=multi-user.target
-EOF
-
chroot ${mntdir} /bin/bash << "EOT"
echo "Enabling services..."
-systemctl enable cleanup
+systemctl enable led
+systemctl enable sd-dupe
echo "Creating Initial Ramdisk..."
update-initramfs -c -t -k "5.2.0"