From f8404ab043cef03d8ffa9a8ad684e757d11b684e Mon Sep 17 00:00:00 2001 From: Aiden McClelland Date: Tue, 13 Jun 2023 18:38:47 -0600 Subject: [PATCH] btrfs --- backend/src/disk/fsck/btrfs.rs | 31 ++++++++++ backend/src/disk/{fsck.rs => fsck/ext4.rs} | 27 +-------- backend/src/disk/fsck/mod.rs | 68 ++++++++++++++++++++++ backend/src/disk/main.rs | 2 +- backend/src/os_install/mod.rs | 7 ++- build/lib/depends | 2 + 6 files changed, 108 insertions(+), 29 deletions(-) create mode 100644 backend/src/disk/fsck/btrfs.rs rename backend/src/disk/{fsck.rs => fsck/ext4.rs} (80%) create mode 100644 backend/src/disk/fsck/mod.rs diff --git a/backend/src/disk/fsck/btrfs.rs b/backend/src/disk/fsck/btrfs.rs new file mode 100644 index 000000000..ce4e89f75 --- /dev/null +++ b/backend/src/disk/fsck/btrfs.rs @@ -0,0 +1,31 @@ +use std::path::Path; + +use tokio::process::Command; +use tracing::instrument; + +use crate::disk::fsck::RequiresReboot; +use crate::util::Invoke; +use crate::Error; + +#[instrument(skip_all)] +pub async fn btrfs_check_readonly(logicalname: impl AsRef) -> Result { + Command::new("btrfs") + .arg("check") + .arg("--readonly") + .arg(logicalname.as_ref()) + .invoke(crate::ErrorKind::DiskManagement) + .await?; + + Ok(RequiresReboot(false)) +} + +pub async fn btrfs_check_repair(logicalname: impl AsRef) -> Result { + Command::new("btrfs") + .arg("check") + .arg("--repair") + .arg(logicalname.as_ref()) + .invoke(crate::ErrorKind::DiskManagement) + .await?; + + Ok(RequiresReboot(false)) +} diff --git a/backend/src/disk/fsck.rs b/backend/src/disk/fsck/ext4.rs similarity index 80% rename from backend/src/disk/fsck.rs rename to backend/src/disk/fsck/ext4.rs index 208c5401e..7bcbbc8b3 100644 --- a/backend/src/disk/fsck.rs +++ b/backend/src/disk/fsck/ext4.rs @@ -7,34 +7,9 @@ use futures::FutureExt; use tokio::process::Command; use tracing::instrument; +use crate::disk::fsck::RequiresReboot; use crate::Error; -#[derive(Debug, Clone, Copy)] -#[must_use] -pub struct RequiresReboot(pub bool); -impl std::ops::BitOrAssign for RequiresReboot { - fn bitor_assign(&mut self, rhs: Self) { - self.0 |= rhs.0 - } -} - -#[derive(Debug, Clone, Copy)] -pub enum RepairStrategy { - Preen, - Aggressive, -} -impl RepairStrategy { - pub async fn e2fsck( - &self, - logicalname: impl AsRef + std::fmt::Debug, - ) -> Result { - match self { - RepairStrategy::Preen => e2fsck_preen(logicalname).await, - RepairStrategy::Aggressive => e2fsck_aggressive(logicalname).await, - } - } -} - #[instrument(skip_all)] pub async fn e2fsck_preen( logicalname: impl AsRef + std::fmt::Debug, diff --git a/backend/src/disk/fsck/mod.rs b/backend/src/disk/fsck/mod.rs new file mode 100644 index 000000000..b3f561366 --- /dev/null +++ b/backend/src/disk/fsck/mod.rs @@ -0,0 +1,68 @@ +use std::path::Path; + +use color_eyre::eyre::eyre; +use tokio::process::Command; + +use crate::disk::fsck::btrfs::{btrfs_check_readonly, btrfs_check_repair}; +use crate::disk::fsck::ext4::{e2fsck_aggressive, e2fsck_preen}; +use crate::util::Invoke; +use crate::Error; + +pub mod btrfs; +pub mod ext4; + +#[derive(Debug, Clone, Copy)] +#[must_use] +pub struct RequiresReboot(pub bool); +impl std::ops::BitOrAssign for RequiresReboot { + fn bitor_assign(&mut self, rhs: Self) { + self.0 |= rhs.0 + } +} + +#[derive(Debug, Clone, Copy)] +pub enum RepairStrategy { + Preen, + Aggressive, +} +impl RepairStrategy { + pub async fn fsck( + &self, + logicalname: impl AsRef + std::fmt::Debug, + ) -> Result { + match &*String::from_utf8( + Command::new("grub-probe") + .arg("-d") + .arg(logicalname.as_ref()) + .invoke(crate::ErrorKind::DiskManagement) + .await?, + )? { + "ext2" => self.e2fsck(logicalname).await, + "btrfs" => self.btrfs_check(logicalname).await, + fs => { + return Err(Error::new( + eyre!("Unknown filesystem {fs}"), + crate::ErrorKind::DiskManagement, + )) + } + } + } + pub async fn e2fsck( + &self, + logicalname: impl AsRef + std::fmt::Debug, + ) -> Result { + match self { + RepairStrategy::Preen => e2fsck_preen(logicalname).await, + RepairStrategy::Aggressive => e2fsck_aggressive(logicalname).await, + } + } + pub async fn btrfs_check( + &self, + logicalname: impl AsRef + std::fmt::Debug, + ) -> Result { + match self { + RepairStrategy::Preen => btrfs_check_readonly(logicalname).await, + RepairStrategy::Aggressive => btrfs_check_repair(logicalname).await, + } + } +} diff --git a/backend/src/disk/main.rs b/backend/src/disk/main.rs index 2ebfc7613..3a338c6af 100644 --- a/backend/src/disk/main.rs +++ b/backend/src/disk/main.rs @@ -124,7 +124,7 @@ pub async fn create_fs>( .arg(format!("{}_{}", guid, name)) .invoke(crate::ErrorKind::DiskManagement) .await?; - Command::new("mkfs.ext4") + Command::new("mkfs.btrfs") .arg(Path::new("/dev/mapper").join(format!("{}_{}", guid, name))) .invoke(crate::ErrorKind::DiskManagement) .await?; diff --git a/backend/src/os_install/mod.rs b/backend/src/os_install/mod.rs index 6ebd33aaf..7009498d7 100644 --- a/backend/src/os_install/mod.rs +++ b/backend/src/os_install/mod.rs @@ -175,12 +175,15 @@ pub async fn execute( } } - Command::new("mkfs.ext4") + Command::new("mkfs.btrfs") .arg(&part_info.root) .invoke(crate::ErrorKind::DiskManagement) .await?; - Command::new("e2label") + Command::new("btrfs") + .arg("property") + .arg("set") .arg(&part_info.root) + .arg("label") .arg("rootfs") .invoke(crate::ErrorKind::DiskManagement) .await?; diff --git a/build/lib/depends b/build/lib/depends index 85340d212..66b26be2e 100644 --- a/build/lib/depends +++ b/build/lib/depends @@ -3,6 +3,7 @@ avahi-utils bash-completion beep bmon +btrfs-progs ca-certificates cifs-utils containerd.io @@ -43,5 +44,6 @@ systemd-resolved systemd-sysv systemd-timesyncd tor +util-linux vim wireless-tools