Skip to content

Commit ff866ad

Browse files
yeazelmvyaghras
authored andcommitted
apiserver: use direct paths for ephemeral storage
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> (cherry picked from commit 86d582e) Signed-off-by: Shikha Vyaghra <vyaghras@amazon.com>
1 parent bcbc3db commit ff866ad

File tree

1 file changed

+25
-36
lines changed

1 file changed

+25
-36
lines changed

sources/api/apiserver/src/server/ephemeral_storage.rs

Lines changed: 25 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ static FINDMNT: &str = "/usr/bin/findmnt";
1818

1919
/// Name of the array (if created) and filesystem label. Selected to be 12 characters so it
2020
/// fits within both the xfs and ext4 volume label limit.
21-
static EPHEMERAL: &str = ".ephemeral";
21+
static EPHEMERAL_MNT: &str = ".ephemeral";
22+
/// Name of the device and its path from the MD driver
23+
static RAID_DEVICE_DIR: &str = "/dev/md/";
24+
static RAID_DEVICE_NAME: &str = "ephemeral";
2225

2326
/// initialize prepares the ephemeral storage for formatting and formats it. For multiple disks
2427
/// preparation is the creation of a RAID0 array, for a single disk this is a no-op. The array or disk
@@ -70,11 +73,14 @@ pub fn initialize(fs: Option<Filesystem>, disks: Option<Vec<String>>) -> Result<
7073
let scan_output = mdadm_scan()?;
7174
// no previously configured array found, so construct a new one
7275
if scan_output.is_empty() {
73-
info!("creating array named {:?} from {:?}", EPHEMERAL, disks);
74-
mdadm_create(EPHEMERAL, disks.iter().map(|x| x.as_str()).collect())?;
76+
info!(
77+
"creating array named {:?} from {:?}",
78+
RAID_DEVICE_NAME, disks
79+
);
80+
mdadm_create(RAID_DEVICE_NAME, disks.iter().map(|x| x.as_str()).collect())?;
7581
}
76-
// can't lookup the array until it's created
77-
resolve_array_by_id()?
82+
// Once it is built, it will be available in `/dev/md/`
83+
format!("{}{}", RAID_DEVICE_DIR, RAID_DEVICE_NAME)
7884
}
7985
};
8086

@@ -95,14 +101,18 @@ pub fn initialize(fs: Option<Filesystem>, disks: Option<Vec<String>>) -> Result<
95101
/// binds the specified directories to the pre-configured array, creating those directories if
96102
/// they do not exist.
97103
pub fn bind(variant: &str, dirs: Vec<String>) -> Result<()> {
98-
// handle the no local instance storage case
99-
if ephemeral_devices()?.is_empty() {
100-
info!("no ephemeral disks found, skipping ephemeral storage binding");
101-
return Ok(());
102-
}
104+
let device_name = match ephemeral_devices()?.len() {
105+
// handle the no local instance storage case
106+
0 => {
107+
info!("no ephemeral disks found, skipping ephemeral storage binding");
108+
return Ok(());
109+
}
110+
// If there is only one device, use that
111+
1 => ephemeral_devices()?.first().expect("non-empty").clone(),
112+
_ => format!("{}{}", RAID_DEVICE_DIR, RAID_DEVICE_NAME),
113+
};
103114

104-
let device_name = resolve_device_by_label()?;
105-
let mount_point = format!("/mnt/{}", EPHEMERAL);
115+
let mount_point = format!("/mnt/{}", EPHEMERAL_MNT);
106116
let mount_point = Path::new(&mount_point);
107117
let allowed_dirs = allowed_bind_dirs(variant);
108118
for dir in &dirs {
@@ -202,34 +212,16 @@ fn is_mounted(path: &String) -> Result<bool> {
202212
Ok(status.success())
203213
}
204214

205-
/// resolve_device_by_label resolves the by-label link for the raid array or single disk to the device name
206-
fn resolve_device_by_label() -> Result<String> {
207-
canonical_name(format!("/dev/disk/by-label/{}", EPHEMERAL))
208-
}
209-
210-
/// resolve_array_by_name resolves the by-id link for the raid array
211-
fn resolve_array_by_id() -> Result<String> {
212-
canonical_name(format!("/dev/disk/by-id/md-name-{}", EPHEMERAL))
213-
}
214-
215-
/// canonical_name will create the canonical, absolute form of a path with all intermediate
216-
/// components normalized and symbolic links resolved
217-
fn canonical_name(name: String) -> Result<String> {
218-
Ok(std::fs::canonicalize(OsString::from(name))
219-
.context(error::CanonicalizeFailureSnafu {})?
220-
.to_string_lossy()
221-
.to_string())
222-
}
223-
224215
/// creates the array with the given name from the specified disks
225216
fn mdadm_create<T: AsRef<str>>(name: T, disks: Vec<T>) -> Result<()> {
226-
let mut device_name = OsString::from("/dev/md/");
217+
let mut device_name = OsString::from(RAID_DEVICE_DIR);
227218
device_name.push(name.as_ref());
228219

229220
let mut cmd = Command::new(MDADM);
230221
cmd.arg("--create");
231222
cmd.arg("--force");
232223
cmd.arg("--verbose");
224+
cmd.arg("--homehost=any");
233225
cmd.arg(device_name);
234226
cmd.arg("--level=0");
235227
// By default, mdadm uses a 512KB chunk size. mkfs.xfs attempts to match some of its settings to
@@ -332,7 +324,7 @@ pub fn format_device<S: AsRef<OsStr>>(device: S, format: &Filesystem) -> Result<
332324
mkfs.arg(device.as_ref());
333325
// labeled, XFS has a max of 12 characters, EXT4 allows 16
334326
mkfs.arg("-L");
335-
mkfs.arg(EPHEMERAL);
327+
mkfs.arg(RAID_DEVICE_NAME);
336328

337329
let output = mkfs
338330
.output()
@@ -405,9 +397,6 @@ pub mod error {
405397

406398
#[snafu(display("Failed to create directory, {}", source))]
407399
Mkdir { source: std::io::Error },
408-
409-
#[snafu(display("Failed to canonicalize path, {}", source))]
410-
CanonicalizeFailure { source: std::io::Error },
411400
}
412401
}
413402

0 commit comments

Comments
 (0)