Skip to contentSkip to conversation

initramfs and UUID support in minimal installer

PATCH In review Chen Qi 1 participant 11 messages Jun 16, 2014 – Jan 12, 2015

lore
Share & tools
lore

Chen Qi

author
#0 lore raw

cover initramfs and UUID support in minimal installer

The purpose of this patchset is to add initramfs and UUID support for our minimal installer.

Previously, the installed image may not be able to boot up because we use the hardcoded disk names.

To reproduce, use the following commands.
1. Enable live image types and build out the minimal installer.
2. runqemu qemux86 iso qemuparams="-hdb target-disk"
3. qemu-system-i386 -hda target-disk

We can see that the installed target cannot boot up correctly.

This patchset fixes this problem so that when executing the above commands, the target can still correctly boot up as long as we configure in local.conf or some other distro config files to select image-initramfs-minimal as the INITRAMFS_IMAGE.

//Chen Qi

The following changes since commit 12bab2d828836c8926f753caff80b61dbe6390a5:

alsa-tools: Add missing pkgconfg dependency (2014-06-14 08:45:47 +0100)

are available in the git repository at:

git://git.openembedded.org/openembedded-core-contrib ChenQi/initramfs-uuid
http://cgit.openembedded.org/cgit.cgi/openembedded-core-contrib/log/?h=ChenQi/busybox-syslog

Chen Qi (9):
initramfs-image-minimal.bb: add recipe
initramfs-framework: fix an error in udev module
initramfs-framework: modify the fatal behaviour in init
initramfs-framework: fix an error in finish module kernel.bbclass: also install the bundled kernel to STAGING_KERNEL_DIR bootimg.bbclass: take initramfs into consideration
initramfs-live-install: rdepend on util-linux-blkid
busybox: enable uuid support by default
init-install.sh: add support for installing initramfs onto the target

 meta/classes/bootimg.bbclass                       |    7 ++-
 meta/classes/kernel.bbclass                        |    1 +
 meta/recipes-core/busybox/busybox/defconfig        |   38 +++++++--------
 .../recipes-core/images/initramfs-image-minimal.bb |   19 ++++++++
 .../initrdscripts/files/init-install.sh            |   49 ++++++++++++++++----
 .../initrdscripts/initramfs-framework/finish       |    4 +-
 .../initrdscripts/initramfs-framework/init         |    5 +-
 .../initrdscripts/initramfs-framework/udev         |    1 +
 .../initrdscripts/initramfs-live-install_1.0.bb    |    2 +-
 9 files changed, 89 insertions(+), 37 deletions(-)
 create mode 100644 meta/recipes-core/images/initramfs-image-minimal.bb
Signature · 1 line
1.7.9.5
author
#1 lore raw

PATCH 1/9 initramfs-image-minimal.bb: add recipe

Add a recipe for a minimal initramfs image.

Note that the purpose of this recipe is totally different from that of core-image-minimal-initramfs.bb. The latter is supposed to be used in the live image to "boot" or "install". The former is more like a traditional initramfs whose responsibility is to deal with the kernel parameters and then bring up the real root file system.

After adding this recipe, we could specify INITRAMFS_IMAGE to be "initramfs-image-minimal". Note that in OE, we didn't have a reference image recipe for INITRAMFS_IMAGE.

---
 .../recipes-core/images/initramfs-image-minimal.bb |   19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
 create mode 100644 meta/recipes-core/images/initramfs-image-minimal.bb
meta/recipes-core/images/initramfs-image-minimal.bb new file +19 -0
new file mode 100644
index 0000000..24501e0
@@ -0,0 +1,19 @@
+# Minimal initramfs image
+DESCRIPTION = "Minimal initramfs image used to bring up the system."
+LICENSE = "MIT"
+
+PACKAGE_INSTALL = "initramfs-framework-base initramfs-module-udev busybox udev base-passwd"
+
+# Do not pollute the initramfs image with rootfs features
+IMAGE_FEATURES = ""
+IMAGE_LINGUAS = ""
+
+IMAGE_FSTYPES = "${INITRAMFS_FSTYPES}"
+inherit image
+
+BAD_RECOMMENDATIONS += "busybox-syslog"
+
+# We need to set USE_DEVFS to "0" here to trigger creation of device nodes at rootfs time.
+# The reason here is that, when this initramfs is bundled into kernel, we need /dev/console
+# to be there before init is run.
+USE_DEVFS = "0"
Signature · 1 line
1.7.9.5
author
#2 lore raw

PATCH 2/9 initramfs-framework: fix an error in udev module

In reply to Chen Qi

The /var/run directory needs to be there in order for udevd to work correctly.

---
 .../initrdscripts/initramfs-framework/udev         |    1 +
 1 file changed, 1 insertion(+)
meta/recipes-core/initrdscripts/initramfs-framework/udev +1 -0
index bb462dc..79c8867 100644
@@ -38,6 +38,7 @@ udev_run() {
 	add_module_pre_hook "udev_shutdown_hook_handler"
 
 	mkdir -p /run
+	mkdir -p /var/run
 
 	$_UDEV_DAEMON --daemon
 	udevadm trigger --action=add
Signature · 1 line
1.7.9.5
author
#3 lore raw

PATCH 3/9 initramfs-framework: modify the fatal behaviour in init

In reply to Chen Qi

When a fatal error occurs, we'd better drop into a shell instead of having it sleep for 3600 seconds.

---
 .../initrdscripts/initramfs-framework/init         |    5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)
meta/recipes-core/initrdscripts/initramfs-framework/init +1 -4
index 95fa9fb..1e3c14c 100755
@@ -56,10 +56,7 @@ debug() {
 fatal() {
     echo $1 >/dev/console
     echo >/dev/console
-
-	while [ "true" ]; do
-		sleep 3600
-	done
+    exec sh
 }
 
 # Variables shared amoung modules
Signature · 1 line
1.7.9.5
author
#4 lore raw

PATCH 4/9 initramfs-framework: fix an error in finish module

In reply to Chen Qi

It's possible that the /dev directory doesn't exist under $ROOTFS_DIR. This should not suggest any invalidity. So instead of erroring out when $ROOTFS_DIR/dev doesn't exist, we create it.

---
 .../initrdscripts/initramfs-framework/finish       |    4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)
meta/recipes-core/initrdscripts/initramfs-framework/finish +1 -3
index 325f47b..1ff0e3e 100755
@@ -28,9 +28,7 @@ finish_run() {
 			fi
 		fi
 
-		if [ ! -d $ROOTFS_DIR/dev ]; then
-			fatal "ERROR: There's no '/dev' on rootfs."
-		fi
+		mkdir -p $ROOTFS_DIR/dev
 
 		info "Switching root to '$ROOTFS_DIR'..."
 
Signature · 1 line
1.7.9.5
author
#5 lore raw

PATCH 5/9 kernel.bbclass: also install the bundled kernel to STAGING_KERNEL_DIR

In reply to Chen Qi

Storing the bundled kernel in ${D} would have the risk of getting deleted by rm_work. It also makes the bundled kernel unavailable to others until the kernel is deployed. So it's better to also install the bundled kernel into ${STAGING_KERNEL_DIR} so that others could use it once do_bundle_initramfs is finished.

---
 meta/classes/kernel.bbclass |    1 +
 1 file changed, 1 insertion(+)
meta/classes/kernel.bbclass +1 -0
index 6ed1cb7..743b9fb 100644
@@ -138,6 +138,7 @@ do_bundle_initramfs () {
 		# Update install area
 		echo "There is kernel image bundled with initramfs: ${B}/${KERNEL_OUTPUT}.initramfs"
 		install -m 0644 ${B}/${KERNEL_OUTPUT}.initramfs ${D}/boot/${KERNEL_IMAGETYPE}-initramfs-${MACHINE}.bin
+		install -m 0644 ${B}/${KERNEL_OUTPUT}.initramfs ${STAGING_KERNEL_DIR}/${KERNEL_IMAGETYPE}-initramfs-${MACHINE}.bin
 		echo "${B}/${KERNEL_OUTPUT}.initramfs"
 	fi
 }
Signature · 1 line
1.7.9.5
author
#6 lore raw

PATCH 6/9 bootimg.bbclass: take initramfs into consideration

In reply to Chen Qi

It's a reasonable assumption that if INITRAMFS_IMAGE is set, the user wants to do something with it. So the bootimg.bbclass should not just ignore the existence of INITRAMFS_IMAGE.

This patch fixes the bootimg.bbclass to ship the initramfs image or the bundled kernel for later use.

---
 meta/classes/bootimg.bbclass |    7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
meta/classes/bootimg.bbclass +6 -1
index 7678567..b925265 100644
@@ -66,6 +66,11 @@ populate() {
 
 	# Install bzImage, initrd, and rootfs.img in DEST for all loaders to use.
 	install -m 0644 ${STAGING_KERNEL_DIR}/bzImage ${DEST}/vmlinuz
+	if [ -n "${INITRAMFS_IMAGE}" ] && [ "${INITRAMFS_IMAGE_BUNDLE}" = "1" ]; then
+		install -m 0644 ${STAGING_KERNEL_DIR}/bzImage-initramfs-${MACHINE}.bin ${DEST}/vmlinuz-initramfs
+	elif [ -n "${INITRAMFS_IMAGE}" ]; then
+		install -m 0644 ${DEPLOY_DIR_IMAGE}/${INITRAMFS_IMAGE}-${MACHINE}.cpio.gz ${DEST}/initrd.img
+	fi
 
 	if [ -n "${INITRD}" ] && [ -s "${INITRD}" ]; then
 		install -m 0644 ${INITRD} ${DEST}/initrd
@@ -237,4 +242,4 @@ IMAGE_TYPEDEP_iso = "ext3"
 IMAGE_TYPEDEP_hddimg = "ext3"
 IMAGE_TYPES_MASKED += "iso hddimg"
 
-addtask bootimg before do_build
+addtask bootimg before do_build after do_bundle_initramfs
Signature · 1 line
1.7.9.5
author
#7 lore raw

PATCH 7/9 initramfs-live-install: rdepend on util-linux-blkid

In reply to Chen Qi

We need the blkid command from util-linux-blkid package to get the UUID of a particular partition.

---
 .../initrdscripts/initramfs-live-install_1.0.bb    |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
meta/recipes-core/initrdscripts/initramfs-live-install_1.0.bb +1 -1
index 7bf31c9..25326eb 100644
@@ -5,7 +5,7 @@ SRC_URI = "file://init-install.sh"
 
 PR = "r9"
 
-RDEPENDS_${PN} = "grub parted e2fsprogs-mke2fs"
+RDEPENDS_${PN} = "grub parted e2fsprogs-mke2fs util-linux-blkid"
 
 do_install() {
         install -m 0755 ${WORKDIR}/init-install.sh ${D}/install.sh
Signature · 1 line
1.7.9.5
author
#8 lore raw

PATCH 8/9 busybox: enable uuid support by default

In reply to Chen Qi

This patch enables several configuration items to enable UUID support by default. This makes busybox's `mount' able to deal with /etc/fstab with lines such as "UUID=xxx / ext4 defaults 0 1".

The CONFIG_FEATURE_VOLUMEID_XXX configuration items need to be enabled, otherwise, the `mount' command from busybox cannot get UUID of the corresponding filesystems.

---
 meta/recipes-core/busybox/busybox/defconfig |   38 +++++++++++++--------------
 1 file changed, 19 insertions(+), 19 deletions(-)
meta/recipes-core/busybox/busybox/defconfig +19 -19
index 47eca21..8a79fde 100644
@@ -576,13 +576,13 @@ CONFIG_LOSETUP=y
 # CONFIG_LSPCI is not set
 # CONFIG_LSUSB is not set
 CONFIG_MKSWAP=y
-# CONFIG_FEATURE_MKSWAP_UUID is not set
+CONFIG_FEATURE_MKSWAP_UUID=y
 CONFIG_MORE=y
 CONFIG_MOUNT=y
 # CONFIG_FEATURE_MOUNT_FAKE is not set
 # CONFIG_FEATURE_MOUNT_VERBOSE is not set
 # CONFIG_FEATURE_MOUNT_HELPERS is not set
-# CONFIG_FEATURE_MOUNT_LABEL is not set
+CONFIG_FEATURE_MOUNT_LABEL=y
 CONFIG_FEATURE_MOUNT_NFS=y
 # CONFIG_FEATURE_MOUNT_CIFS is not set
 CONFIG_FEATURE_MOUNT_FLAGS=y
@@ -608,23 +608,23 @@ CONFIG_FEATURE_MOUNT_LOOP=y
 CONFIG_FEATURE_MOUNT_LOOP_CREATE=y
 # CONFIG_FEATURE_MTAB_SUPPORT is not set
 # CONFIG_VOLUMEID is not set
-# CONFIG_FEATURE_VOLUMEID_EXT is not set
-# CONFIG_FEATURE_VOLUMEID_BTRFS is not set
-# CONFIG_FEATURE_VOLUMEID_REISERFS is not set
-# CONFIG_FEATURE_VOLUMEID_FAT is not set
-# CONFIG_FEATURE_VOLUMEID_HFS is not set
-# CONFIG_FEATURE_VOLUMEID_JFS is not set
-# CONFIG_FEATURE_VOLUMEID_XFS is not set
-# CONFIG_FEATURE_VOLUMEID_NTFS is not set
-# CONFIG_FEATURE_VOLUMEID_ISO9660 is not set
-# CONFIG_FEATURE_VOLUMEID_UDF is not set
-# CONFIG_FEATURE_VOLUMEID_LUKS is not set
-# CONFIG_FEATURE_VOLUMEID_LINUXSWAP is not set
-# CONFIG_FEATURE_VOLUMEID_CRAMFS is not set
-# CONFIG_FEATURE_VOLUMEID_ROMFS is not set
-# CONFIG_FEATURE_VOLUMEID_SYSV is not set
-# CONFIG_FEATURE_VOLUMEID_OCFS2 is not set
-# CONFIG_FEATURE_VOLUMEID_LINUXRAID is not set
+CONFIG_FEATURE_VOLUMEID_EXT=y
+CONFIG_FEATURE_VOLUMEID_BTRFS=y
+CONFIG_FEATURE_VOLUMEID_REISERFS=y
+CONFIG_FEATURE_VOLUMEID_FAT=y
+CONFIG_FEATURE_VOLUMEID_HFS=y
+CONFIG_FEATURE_VOLUMEID_JFS=y
+CONFIG_FEATURE_VOLUMEID_XFS=y
+CONFIG_FEATURE_VOLUMEID_NTFS=y
+CONFIG_FEATURE_VOLUMEID_ISO9660=y
+CONFIG_FEATURE_VOLUMEID_UDF=y
+CONFIG_FEATURE_VOLUMEID_LUKS=y
+CONFIG_FEATURE_VOLUMEID_LINUXSWAP=y
+CONFIG_FEATURE_VOLUMEID_CRAMFS=y
+CONFIG_FEATURE_VOLUMEID_ROMFS=y
+CONFIG_FEATURE_VOLUMEID_SYSV=y
+CONFIG_FEATURE_VOLUMEID_OCFS2=y
+CONFIG_FEATURE_VOLUMEID_LINUXRAID=y
 
 #
 # Miscellaneous Utilities
Signature · 1 line
1.7.9.5
author
#9 lore raw

PATCH 9/9 init-install.sh: add support for installing initramfs onto the target

In reply to Chen Qi

Add support to install initramfs image or the kernel bundled with it onto the target. And if there's an initramfs image available, we try to use the 'root=UUID=xxx' in the grub entry so that the target can always boot up even if the device names are changed, say, from /dev/hdb to /dev/hda.

---
 .../initrdscripts/files/init-install.sh            |   49 ++++++++++++++++----
 1 file changed, 40 insertions(+), 9 deletions(-)
meta/recipes-core/initrdscripts/files/init-install.sh +40 -9
index 0a1141a..748a9d8 100644
@@ -151,25 +151,55 @@ mkdir /tgt_root
 mkdir /src_root
 mkdir -p /boot
 
-# Handling of the target root partition
+# mount target filesystems
+mount $bootfs /boot
 mount $rootfs /tgt_root
+
+# Check whether an initramfs is available and get uuid of filesystems
+has_initramfs=""
+uuid_rootfs=""
+uuid_bootfs=""
+uuid_swap=""
+if [ -e /run/media/$1/vmlinuz-initramfs -o -e /run/media/$1/initrd.img ]; then
+    has_initramfs="yes"
+    uuid_rootfs="`blkid $rootfs | cut -d' ' -f2 | sed -e 's/\"//g'`"
+    uuid_bootfs="`blkid $bootfs | cut -d' ' -f2 | sed -e 's/\"//g'`"
+    uuid_swap="`blkid $swap | cut -d' ' -f2 | sed -e 's/\"//g'`"
+fi
+
+# Handling of the target root partition
 mount -o rw,loop,noatime,nodiratime /run/media/$1/$2 /src_root
 echo "Copying rootfs files..."
 cp -a /src_root/* /tgt_root
+# Try to use uuid entries in /etc/fstab
+if [ "$has_initramfs" = "yes" ]; then
+    swap="$uuid_swap"
+    bootfs="$uuid_bootfs"
+fi
 if [ -d /tgt_root/etc/ ] ; then
     echo "$swap                swap             swap       defaults              0  0" >> /tgt_root/etc/fstab
     echo "$bootfs              /boot            ext3       defaults              1  2" >> /tgt_root/etc/fstab
-    # We dont want udev to mount our root device while we're booting...
-    if [ -d /tgt_root/etc/udev/ ] ; then
-	echo "/dev/${device}" >> /tgt_root/etc/udev/mount.blacklist
-    fi
 fi
-umount /tgt_root
 umount /src_root
 
 # Handling of the target boot partition
-mount $bootfs /boot
 echo "Preparing boot partition..."
+
+# If there's an initramfs available, try to use UUID in grub.cfg.
+# We assume the initramfs has the ability to deal with the UUID parameter.
+if [ -e /run/media/$1/vmlinuz-initramfs ]; then
+    cp /run/media/$1/vmlinuz-initramfs /boot/vmlinuz
+    rootfs="$uuid_rootfs"
+else
+    cp /run/media/$1/vmlinuz /boot/
+fi
+
+if [ -e /run/media/$1/initrd.img ]; then
+    cp /run/media/$1/initrd.img /boot/initrd.img
+    rootfs="$uuid_rootfs"
+    initrd_line="initrd /initrd.img"
+fi
+
 if [ -f /etc/grub.d/00_header ] ; then
     echo "Preparing custom grub2 menu..."
     GRUBCFG="/boot/grub/grub.cfg"
@@ -178,6 +208,7 @@ if [ -f /etc/grub.d/00_header ] ; then
 menuentry "Linux" {
     set root=(hd0,1)
     linux /vmlinuz root=$rootfs $rootwait rw $5 $3 $4 quiet
+    $initrd_line
 }
 _EOF
     chmod 0444 $GRUBCFG
@@ -195,8 +226,8 @@ if [ ! -f /boot/grub/grub.cfg ] ; then
     echo "kernel /vmlinuz root=$rootfs rw $3 $4 quiet" >> /boot/grub/menu.lst
 fi
 
-cp /run/media/$1/vmlinuz /boot/
-
+# umount target filesystems
+umount /tgt_root
 umount /boot
 
 sync
Signature · 1 line
1.7.9.5
author
#10 lore raw
In reply to Chen Qi
Quoted 9 lines · Chen Qi

The purpose of this patchset is to add initramfs and UUID support for our minimal installer.

Previously, the installed image may not be able to boot up because we use the hardcoded disk names.

To reproduce, use the following commands.
1. Enable live image types and build out the minimal installer.
2. runqemu qemux86 iso qemuparams="-hdb target-disk"
3. qemu-system-i386 -hda target-disk

I recently noticed that other people on mailing list also noticed the problem described above. This patchset provides one way to solve the problem.

Please help review the patches. Any comment or suggest is really welcome.

Regards,
Chen Qi

Quoted 40 lines

We can see that the installed target cannot boot up correctly.

This patchset fixes this problem so that when executing the above commands, the target can still correctly boot up as long as we configure in local.conf or some other distro config files to select image-initramfs-minimal as the INITRAMFS_IMAGE.

//Chen Qi

The following changes since commit 12bab2d828836c8926f753caff80b61dbe6390a5:

   alsa-tools: Add missing pkgconfg dependency (2014-06-14 08:45:47 +0100)

are available in the git repository at:

git://git.openembedded.org/openembedded-core-contrib ChenQi/initramfs-uuid
http://cgit.openembedded.org/cgit.cgi/openembedded-core-contrib/log/?h=ChenQi/busybox-syslog

Chen Qi (9):
initramfs-image-minimal.bb: add recipe
initramfs-framework: fix an error in udev module
initramfs-framework: modify the fatal behaviour in init
initramfs-framework: fix an error in finish module kernel.bbclass: also install the bundled kernel to STAGING_KERNEL_DIR bootimg.bbclass: take initramfs into consideration
initramfs-live-install: rdepend on util-linux-blkid
busybox: enable uuid support by default
init-install.sh: add support for installing initramfs onto the target

  meta/classes/bootimg.bbclass                       |    7 ++-
  meta/classes/kernel.bbclass                        |    1 +
  meta/recipes-core/busybox/busybox/defconfig        |   38 +++++++--------
  .../recipes-core/images/initramfs-image-minimal.bb |   19 ++++++++
  .../initrdscripts/files/init-install.sh            |   49 ++++++++++++++++----
  .../initrdscripts/initramfs-framework/finish       |    4 +-
  .../initrdscripts/initramfs-framework/init         |    5 +-
  .../initrdscripts/initramfs-framework/udev         |    1 +
  .../initrdscripts/initramfs-live-install_1.0.bb    |    2 +-
  9 files changed, 89 insertions(+), 37 deletions(-)

create mode 100644 meta/recipes-core/images/initramfs-image-minimal.bb