В настоящее время я работаю над структурой обновления программного обеспечения. подкачка. В качестве схемы обновления я выбрал метод двойного копирования. Я установил Ubuntu 20.04 на свое целевое устройство (настольный ПК -> i5,32GB SSD, BIOS,..) для тестирования и разделил его соответствующим образом.
/dev/sda1 --/загрузка
/dev/sda2 --/
/dev/sda3 --/root2
/dev/sda4 --/данные
В целях тестирования я создал образ корневой файловой системы из хост-системы (/dev/sda2) с помощью команды «dd». Я присвоил изображению новый UUID и метку с помощью команд «tune2fs» и «e2label».
dd if=/dev/sda2 of=rootfs.img status=progress
e2label rootfs.img root2
e2fsck -fy rootfs.img
tune2fs -U случайный rootfs.img
Необходимо иметь механизм координации между загрузчиком и агентом обновлений, чтобы после успешного обновления загрузить систему со вторичным разделом rootfs.Загрузчик должен убедиться, какой раздел rootfs (A или B) загружен.
Ubuntu использует GRUB в качестве стандартного загрузчика. GRUB предоставляет «блок среды», который можно использовать для сохранения небольшого количества состояния (/boot/grub/grubenv). Агент обновления SWUpdate имеет обработчик загрузчика для управления этим файлом. SWupdate может добавлять в этот файл переменные окружения. SWupdate может вызывать сценарии до и после установки образов (pre-postinstall).
Я написал сценарий bash, который считывает текущий раздел rootfs из командной строки ядра (/proc/cmdline) и переменные среды из блока среды GRUB (/boot/grub/grubenv), чтобы обновить раздел rootfs после обновления. процесс через файл конфигурации загрузчика по умолчанию (/etc/default/grub), с которым загружается система.
CONFIG_FILE=/etc/по умолчанию/жратвы
ROOTFS1_UUID=$(blkid -o значение -s UUID /dev/sda2)
ROOTFS2_UUID=$(blkid -o значение -s UUID /dev/sda3)
функция get_UUID_of_current_boot_device() {
для i в `cat /proc/cmdline`; делать
случай "$i" в
корень=*)
КОРЕНЬ="${i#root=UUID=}"
;;
эсак
сделано
}
функция get_partition_number_of_current_boot_device() {
если [[$ROOT = $ROOTFS1_UUID]]; тогда
CURRENT_PARTITION="2";
Элиф [[$ROOT = $ROOTFS2_UUID]]; тогда
CURRENT_PARTITION="3";
еще
echo "Ошибка схемы раздела!!"
фи
}
функция get_bootloader_env() {
для i в `cat /boot/grub/grubenv`; делать
случай "$i" в
загрузочная часть=*)
BOOT_DEVICE="${i#bootpart=}"
;;
эсак
сделано
}
функция set_boot_device_UUID() {
если [ $BOOT_DEVICE = "2" ]; тогда
BOOT_DEVICE_UUID="$ROOTFS1_UUID";
Элиф [ $ BOOT_DEVICE = "3" ]; тогда
BOOT_DEVICE_UUID="$ROOTFS2_UUID";
еще
эхо "";
BOOT_DEVICE_UUID="$ROOT";
фи
}
Насколько я читал до сих пор, чтобы навсегда изменить параметры командной строки ядра, необходимые параметры должны быть настроены в строке GRUB_CMDLINE_LINUX_DEFAULT или в строке GRUB_CMDLINE_LINUX. В своем сценарии я изменил эту строку, чтобы переменная $BOOT_DEVICE_UUID всегда была разделом rootfs, который должен загружаться после перезагрузки.
sed -i "s/\(GRUB_CMDLINE_LINUX *= *\).*/\1\"$BOOT_DEVICE_UUID\"/" $CONFIG_FILE;
К сожалению, это не сработало, я думал, что значение существующей переменной «root» в командной строке будет заменено значением, которое я передал.
Загрузчик должен каким-то образом выбрать через переменные среды, какой раздел Rootfs, содержащий систему Linux, должен быть загружен. Может ли кто-нибудь объяснить мне, в чем моя ошибка, и может ли кто-нибудь привести мне конкретный пример по этой теме?