From bf238cc190b32536247bcfe2c1e7b7cc1de5f821 Mon Sep 17 00:00:00 2001 From: Nikita Dubrovskii Date: Tue, 12 Jul 2022 12:54:33 +0200 Subject: [PATCH 1/2] blockdev: use 'blkid' for reading device's UUID firstboot of RHCOS on IBM zKVM from time to time fails during "File System Check". This happens, because systemd unit has an old filesystem's UUID from pristine qcow2 image, not the regenerated one: ``` coreos-boot-edit: + lsblk -o NAME,LABEL,UUID --paths --pairs /dev/disk/by-label/boot coreos-boot-edit: NAME="/dev/mapper/crypt_bootfs" LABEL="boot" UUID="96d15588-3596-4b3c-adca-a2ff7279ea63" coreos-boot-edit: + blkid /dev/disk/by-label/boot coreos-boot-edit: /dev/disk/by-label/boot: LABEL="boot" UUID="eee55c4f-c2df-47e9-a284-992e9e122a97" BLOCK_SIZE="1024" TYPE="ext4" coreos-boot-edit: + rdcore bind-boot /sysroot /mnt/boot_partition ..... coreos-boot-mount-generator: ++ cat /run/coreos/bootfs_uuid coreos-boot-mount-generator: + bootdev=/dev/disk/by-uuid/96d15588-3596-4b3c-adca-a2ff7279ea63 ``` Signed-off-by: Nikita Dubrovskii --- src/blockdev.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/blockdev.rs b/src/blockdev.rs index 1e11da3ac..42b73d407 100644 --- a/src/blockdev.rs +++ b/src/blockdev.rs @@ -466,7 +466,7 @@ impl Mount { } pub fn get_filesystem_uuid(&self) -> Result { - let devinfo = lsblk_single(Path::new(&self.device))?; + let devinfo = blkid_single(Path::new(&self.device))?; devinfo .get("UUID") .map(String::from) @@ -876,6 +876,17 @@ fn blkid() -> Result>> { Ok(result) } +pub fn blkid_single(dev: &Path) -> Result> { + let mut cmd = Command::new("blkid"); + cmd.arg(dev); + let output = cmd_output(&mut cmd)?; + if output.is_empty() { + // this should never happen because `blkid` itself would've failed + bail!("no blkid results for {}", dev.display()); + } + Ok(split_blkid_line(&output)) +} + /// This is a bit fuzzy, but... this function will return every block device in the parent /// hierarchy of `device` capable of containing other partitions. So e.g. parent devices of type /// "part" doesn't match, but "disk" and "mpath" does. From 5221ff24b9e2fa4e729a985f17fc4cd3b66bdc23 Mon Sep 17 00:00:00 2001 From: Nikita Dubrovskii Date: Tue, 12 Jul 2022 14:50:08 +0200 Subject: [PATCH 2/2] blockdev: remove 'lsblk_single' and use 'blkid_single' instead --- src/bin/rdcore/rootmap.rs | 9 +++------ src/blockdev.rs | 7 +++++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/bin/rdcore/rootmap.rs b/src/bin/rdcore/rootmap.rs index 5036e1f05..c07a4e469 100644 --- a/src/bin/rdcore/rootmap.rs +++ b/src/bin/rdcore/rootmap.rs @@ -85,9 +85,9 @@ pub fn get_boot_mount_from_cmdline_args( if let Some(path) = boot_mount { Ok(Some(Mount::from_existing(path)?)) } else if let Some(devpath) = boot_device { - let devinfo = lsblk_single(Path::new(devpath))?; + let devinfo = blkid_single(Path::new(devpath))?; let fs = devinfo - .get("FSTYPE") + .get("TYPE") .with_context(|| format!("failed to query filesystem for {}", devpath))?; Ok(Some(Mount::try_mount( devpath, @@ -100,10 +100,7 @@ pub fn get_boot_mount_from_cmdline_args( } fn device_to_kargs(root: &Mount, device: PathBuf) -> Result>> { - let blkinfo = lsblk_single(&device)?; - let blktype = blkinfo - .get("TYPE") - .with_context(|| format!("missing TYPE for {}", device.display()))?; + let blktype = get_block_device_type(&device)?; // a `match {}` construct would be nice here, but for RAID it's a prefix match if blktype.starts_with("raid") || blktype == "linear" { Ok(Some(get_raid_kargs(&device)?)) diff --git a/src/blockdev.rs b/src/blockdev.rs index 42b73d407..d1597a1ce 100644 --- a/src/blockdev.rs +++ b/src/blockdev.rs @@ -772,13 +772,16 @@ fn read_sysfs_dev_block_value(maj: u64, min: u64, field: &str) -> Result Ok(read_to_string(&path)?.trim_end().into()) } -pub fn lsblk_single(dev: &Path) -> Result> { +pub fn get_block_device_type(dev: &Path) -> Result { let mut devinfos = lsblk(Path::new(dev), false)?; if devinfos.is_empty() { // this should never happen because `lsblk` itself would've failed bail!("no lsblk results for {}", dev.display()); } - Ok(devinfos.remove(0)) + devinfos + .remove(0) + .remove("TYPE") + .with_context(|| format!("missing TYPE for {}", dev.display())) } /// Returns all available filesystems.