diff --git a/src/install.rs b/src/install.rs index 973fa1d44..b9653349f 100644 --- a/src/install.rs +++ b/src/install.rs @@ -23,6 +23,7 @@ use std::io::{copy, Read, Seek, SeekFrom, Write}; use std::num::NonZeroU32; use std::os::unix::fs::{FileTypeExt, PermissionsExt}; use std::path::{Path, PathBuf}; +use std::process::{Command, Stdio}; use crate::blockdev::*; use crate::cmdline::*; @@ -241,6 +242,10 @@ pub fn install(config: &InstallConfig) -> Result<()> { bail!("install failed"); } + // fail if we have more than 1 partition with boot/root label + ensure_single_partition("boot", &config.device)?; + ensure_single_partition("root", &config.device)?; + eprintln!("Install complete."); Ok(()) } @@ -401,6 +406,37 @@ fn write_disk( Ok(()) } +fn ensure_single_partition(label: &str, disk: &str) -> Result<()> { + let label = format!("{} ", label); + let cmd = Command::new("lsblk") + .arg("-o") + .arg("LABEL,NAME") + .arg("--noheadings") + .arg("--list") + .arg("--paths") + .stderr(Stdio::inherit()) + .output() + .context("reading partitions' labels")?; + if !cmd.status.success() { + bail!("lsblk failed"); + } + + let pts = std::str::from_utf8(&cmd.stdout) + .context("decoding lsblk output")? + .trim() + .lines() + .filter(|&s| s.starts_with(&label)) + .filter_map(|s| s.split_whitespace().last()) + .collect::>(); + if pts.len() > 1 { + bail!( + "System has several partitions with '{}' label: {:?}.\nPlease `wipefs` all disks except: {}, than you can safely reboot", + label, pts, disk + ); + } + Ok(()) +} + /// Write the Ignition config. fn write_ignition( mountpoint: &Path,