lvm: PV also match udev filter
This commit is contained in:
@ -1,11 +1,11 @@
|
|||||||
use eyre::{Result, format_err};
|
use eyre::{format_err, Result};
|
||||||
use log::{error, info, warn};
|
use log::{error, info, warn};
|
||||||
use tokio::process::Command;
|
use tokio::process::Command;
|
||||||
|
|
||||||
use super::{USED_DEVS, exec, retry, retry_or_ignore};
|
use super::{exec, retry, retry_or_ignore, USED_DEVS};
|
||||||
use crate::fs::walk_dir;
|
use crate::fs::walk_dir;
|
||||||
use crate::{blockdev, lvm};
|
use crate::{blockdev, lvm};
|
||||||
use dkl::bootstrap::{Config, Filesystem, LvSize, LvmLV, LvmVG, TAKE_ALL};
|
use dkl::bootstrap::{Config, Filesystem, LvSize, LvmLV, LvmPV, LvmVG, TAKE_ALL};
|
||||||
|
|
||||||
pub async fn setup(cfg: &Config) {
|
pub async fn setup(cfg: &Config) {
|
||||||
if cfg.lvm.is_empty() {
|
if cfg.lvm.is_empty() {
|
||||||
@ -73,24 +73,12 @@ async fn setup_vg(vg: &LvmVG) -> Result<()> {
|
|||||||
info!("setting up LVM VG {vg_name} ({dev_done}/{dev_needed} devices configured)");
|
info!("setting up LVM VG {vg_name} ({dev_done}/{dev_needed} devices configured)");
|
||||||
}
|
}
|
||||||
|
|
||||||
let regexps: Vec<regex::Regex> = (vg.pvs.regexps.iter())
|
let matching_devs = find_devs(&vg.pvs).await?;
|
||||||
.filter_map(|re_str| {
|
|
||||||
(re_str.parse())
|
|
||||||
.inspect_err(|e| error!("invalid regex ignored: {re_str:?}: {e}"))
|
|
||||||
.ok()
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let mut used_devs = USED_DEVS.lock().await;
|
|
||||||
|
|
||||||
let matching_devs = (walk_dir("/dev").await.into_iter())
|
|
||||||
.filter(|path| !used_devs.contains(path.as_str()))
|
|
||||||
.filter(|path| regexps.iter().any(|re| re.is_match(path)));
|
|
||||||
|
|
||||||
let devs: Vec<_> = if dev_needed == TAKE_ALL {
|
let devs: Vec<_> = if dev_needed == TAKE_ALL {
|
||||||
matching_devs.collect()
|
matching_devs
|
||||||
} else {
|
} else {
|
||||||
matching_devs.take(missing_count!()).collect()
|
matching_devs.into_iter().take(missing_count!()).collect()
|
||||||
};
|
};
|
||||||
|
|
||||||
let cmd = if dev_done == 0 {
|
let cmd = if dev_done == 0 {
|
||||||
@ -109,7 +97,7 @@ async fn setup_vg(vg: &LvmVG) -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dev_done += devs.len();
|
dev_done += devs.len();
|
||||||
used_devs.extend(devs);
|
USED_DEVS.lock().await.extend(devs);
|
||||||
|
|
||||||
if dev_needed != TAKE_ALL && dev_done < (dev_needed as usize) {
|
if dev_needed != TAKE_ALL && dev_done < (dev_needed as usize) {
|
||||||
return Err(format_err!(
|
return Err(format_err!(
|
||||||
@ -213,3 +201,33 @@ async fn install_package(pkg: &str) -> Result<()> {
|
|||||||
Err(format_err!("failed to install package {pkg}: {status}"))
|
Err(format_err!("failed to install package {pkg}: {status}"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn find_devs(pvs: &LvmPV) -> Result<Vec<String>> {
|
||||||
|
let mut results = if let Some(ref filter) = pvs.udev {
|
||||||
|
use crate::udev;
|
||||||
|
let filter: udev::Filter = filter.clone().into();
|
||||||
|
(udev::all().await?.iter())
|
||||||
|
.filter(|dev| dev.subsystem() == Some("block") && filter.matches(dev))
|
||||||
|
.filter_map(|dev| dev.property("DEVNAME").map(|s| s.to_string()))
|
||||||
|
.collect()
|
||||||
|
} else if !pvs.regexps.is_empty() {
|
||||||
|
let regexps: Vec<regex::Regex> = (pvs.regexps.iter())
|
||||||
|
.filter_map(|re_str| {
|
||||||
|
(re_str.parse())
|
||||||
|
.inspect_err(|e| error!("invalid regex ignored: {re_str:?}: {e}"))
|
||||||
|
.ok()
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
(walk_dir("/dev").await.into_iter())
|
||||||
|
.filter(|path| regexps.iter().any(|re| re.is_match(path)))
|
||||||
|
.collect()
|
||||||
|
} else {
|
||||||
|
warn!("no device filters, no matches");
|
||||||
|
vec![]
|
||||||
|
};
|
||||||
|
|
||||||
|
let used_devs = USED_DEVS.lock().await;
|
||||||
|
results.retain(|path| !used_devs.contains(path.as_str()));
|
||||||
|
Ok(results)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user