Skip to content

Commit

Permalink
Merge pull request #191 from jlebon/pr/osmet-prep
Browse files Browse the repository at this point in the history
blockdev: preparatory patches for osmet
  • Loading branch information
Luca Bruno authored Mar 20, 2020
2 parents 64fe36e + d1120d9 commit b066a23
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 27 deletions.
58 changes: 32 additions & 26 deletions src/blockdev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@
// limitations under the License.

use error_chain::bail;
use nix::errno::Errno;
use nix::{self, ioctl_none, ioctl_read_bad, mount, request_code_none};
use nix::{errno::Errno, mount};
use regex::Regex;
use std::collections::HashMap;
use std::convert::TryInto;
Expand All @@ -30,28 +29,36 @@ use tempfile;

use crate::errors::*;

pub fn mount_boot(device: &str) -> Result<Mount> {
pub fn mount_partition_by_label(device: &str, label: &str, flags: mount::MsFlags) -> Result<Mount> {
// get partition list
let partitions = get_partitions(device)?;
if partitions.is_empty() {
bail!("couldn't find any partitions on {}", device);
}

// find the boot partition
let boot_partitions = partitions
// find the partition with the matching label
let matching_partitions = partitions
.iter()
.filter(|d| d.label.as_ref().unwrap_or(&"".to_string()) == "boot")
.filter(|d| d.label.as_ref().unwrap_or(&"".to_string()) == label)
.collect::<Vec<&BlkDev>>();
let dev = match boot_partitions.len() {
0 => bail!("couldn't find boot device for {}", device),
1 => boot_partitions[0],
_ => bail!("found multiple devices on {} with label \"boot\"", device),
let dev = match matching_partitions.len() {
0 => bail!("couldn't find {} device for {}", label, device),
1 => matching_partitions[0],
_ => bail!(
"found multiple devices on {} with label \"{}\"",
device,
label
),
};

// mount it
match &dev.fstype {
Some(fstype) => Mount::try_mount(&dev.path, &fstype),
None => Err(format!("couldn't get filesystem type of boot device for {}", device).into()),
Some(fstype) => Mount::try_mount(&dev.path, &fstype, flags),
None => Err(format!(
"couldn't get filesystem type of {} device for {}",
label, device
)
.into()),
}
}

Expand Down Expand Up @@ -126,7 +133,7 @@ pub struct Mount {
}

impl Mount {
fn try_mount(device: &str, fstype: &str) -> Result<Mount> {
fn try_mount(device: &str, fstype: &str, flags: mount::MsFlags) -> Result<Mount> {
let tempdir = tempfile::Builder::new()
.prefix("coreos-installer-")
.tempdir()
Expand All @@ -135,14 +142,8 @@ impl Mount {
// the partition contents if umount failed
let mountpoint = tempdir.into_path();

mount::mount::<str, Path, str, str>(
Some(device),
&mountpoint,
Some(fstype),
mount::MsFlags::empty(),
None,
)
.chain_err(|| format!("mounting device {} on {}", device, mountpoint.display()))?;
mount::mount::<str, Path, str, str>(Some(device), &mountpoint, Some(fstype), flags, None)
.chain_err(|| format!("mounting device {} on {}", device, mountpoint.display()))?;

Ok(Mount {
device: device.to_string(),
Expand Down Expand Up @@ -184,7 +185,7 @@ pub fn reread_partition_table(file: &mut File) -> Result<()> {
// Reread sometimes fails inexplicably. Retry several times before
// giving up.
for retries in (0..20).rev() {
let result = unsafe { blkrrpart(fd) };
let result = unsafe { ioctl::blkrrpart(fd) };
match result {
Ok(_) => break,
Err(err) => {
Expand All @@ -209,10 +210,10 @@ pub fn reread_partition_table(file: &mut File) -> Result<()> {
}

/// Get the logical sector size of a block device.
pub fn get_sector_size(file: &mut File) -> Result<NonZeroU32> {
pub fn get_sector_size(file: &File) -> Result<NonZeroU32> {
let fd = file.as_raw_fd();
let mut size: c_int = 0;
match unsafe { blksszget(fd, &mut size) } {
match unsafe { ioctl::blksszget(fd, &mut size) } {
Ok(_) => {
let size_u32: u32 = size
.try_into()
Expand All @@ -224,8 +225,13 @@ pub fn get_sector_size(file: &mut File) -> Result<NonZeroU32> {
}

// create unsafe ioctl wrappers
ioctl_none!(blkrrpart, 0x12, 95);
ioctl_read_bad!(blksszget, request_code_none!(0x12, 104), c_int);
#[allow(clippy::missing_safety_doc)]
mod ioctl {
use super::c_int;
use nix::{ioctl_none, ioctl_read_bad, request_code_none};
ioctl_none!(blkrrpart, 0x12, 95);
ioctl_read_bad!(blksszget, request_code_none!(0x12, 104), c_int);
}

pub fn udev_settle() -> Result<()> {
// "udevadm settle" silently no-ops if the udev socket is missing, and
Expand Down
3 changes: 2 additions & 1 deletion src/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
// limitations under the License.

use error_chain::{bail, ChainedError};
use nix::mount;
use std::fs::{create_dir_all, read_dir, File, OpenOptions};
use std::io::{copy, Read, Seek, SeekFrom, Write};
use std::os::unix::fs::FileTypeExt;
Expand Down Expand Up @@ -111,7 +112,7 @@ fn write_disk(

// postprocess
if ignition.is_some() || config.firstboot_kargs.is_some() || config.platform.is_some() {
let mount = mount_boot(&config.device)?;
let mount = mount_partition_by_label(&config.device, "boot", mount::MsFlags::empty())?;
if let Some(ignition) = ignition {
write_ignition(mount.mountpoint(), ignition)?;
}
Expand Down

0 comments on commit b066a23

Please sign in to comment.