Skip to content

Commit

Permalink
apiserver: use direct paths for ephemeral storage
Browse files Browse the repository at this point in the history
The path for ephemeral storage devices is created by udev on early boot
after ephemeral-storage init is called but if you call ephemeral-storage
bind immediately after this, the path may not exist, causing the
resulting commands to fail. This commit switches to a path that is known
to exist to avoid this issue.

Signed-off-by: Matthew Yeazel <yeazelm@amazon.com>
  • Loading branch information
yeazelm committed Sep 9, 2024
1 parent f7abe7b commit e5dd46f
Showing 1 changed file with 12 additions and 30 deletions.
42 changes: 12 additions & 30 deletions sources/api/apiserver/src/server/ephemeral_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,10 @@ pub fn initialize(fs: Option<Filesystem>, disks: Option<Vec<String>>) -> Result<
// no previously configured array found, so construct a new one
if scan_output.is_empty() {
info!("creating array named {:?} from {:?}", EPHEMERAL, disks);
mdadm_create(EPHEMERAL, disks.iter().map(|x| x.as_str()).collect())?;
mdadm_create("ephemeral", disks.iter().map(|x| x.as_str()).collect())?;
}
// can't lookup the array until it's created
resolve_array_by_id()?
"/dev/md/ephemeral".to_string()
}
};

Expand All @@ -95,13 +95,17 @@ pub fn initialize(fs: Option<Filesystem>, disks: Option<Vec<String>>) -> Result<
/// binds the specified directories to the pre-configured array, creating those directories if
/// they do not exist.
pub fn bind(variant: &str, dirs: Vec<String>) -> Result<()> {
// handle the no local instance storage case
if ephemeral_devices()?.is_empty() {
info!("no ephemeral disks found, skipping ephemeral storage binding");
return Ok(());
}
let device_name = match ephemeral_devices()?.len() {
// handle the no local instance storage case
0 => {
info!("no ephemeral disks found, skipping ephemeral storage binding");
return Ok(());
}
// If there is only one device, use that
1 => ephemeral_devices()?.first().expect("non-empty").clone(),
_ => "/dev/md/ephemeral".to_string(),
};

let device_name = resolve_device_by_label()?;
let mount_point = format!("/mnt/{}", EPHEMERAL);
let mount_point = Path::new(&mount_point);
let allowed_dirs = allowed_bind_dirs(variant);
Expand Down Expand Up @@ -202,25 +206,6 @@ fn is_mounted(path: &String) -> Result<bool> {
Ok(status.success())
}

/// resolve_device_by_label resolves the by-label link for the raid array or single disk to the device name
fn resolve_device_by_label() -> Result<String> {
canonical_name(format!("/dev/disk/by-label/{}", EPHEMERAL))
}

/// resolve_array_by_name resolves the by-id link for the raid array
fn resolve_array_by_id() -> Result<String> {
canonical_name(format!("/dev/disk/by-id/md-name-{}", EPHEMERAL))
}

/// canonical_name will create the canonical, absolute form of a path with all intermediate
/// components normalized and symbolic links resolved
fn canonical_name(name: String) -> Result<String> {
Ok(std::fs::canonicalize(OsString::from(name))
.context(error::CanonicalizeFailureSnafu {})?
.to_string_lossy()
.to_string())
}

/// creates the array with the given name from the specified disks
fn mdadm_create<T: AsRef<str>>(name: T, disks: Vec<T>) -> Result<()> {
let mut device_name = OsString::from("/dev/md/");
Expand Down Expand Up @@ -405,9 +390,6 @@ pub mod error {

#[snafu(display("Failed to create directory, {}", source))]
Mkdir { source: std::io::Error },

#[snafu(display("Failed to canonicalize path, {}", source))]
CanonicalizeFailure { source: std::io::Error },
}
}

Expand Down

0 comments on commit e5dd46f

Please sign in to comment.