mirror of
https://github.com/vhaudiquet/ecrou.git
synced 2026-11-12 22:22:44 +00:00
fix(guest): diagnose and fail on mount errors in the init
A virtiofs mount that failed (bad fsconfig, missing share) was swallowed: the payload ran without its data and the only symptom was a confusing failure downstream. The init now names the share tag and target on the console and exits 126 - the same contract as an unreachable workdir - instead of booting a run that cannot do its job.
This commit is contained in:
1 parent
f3cbf16180
commit
6bece1098b
1 file changed
+18
-4
@@ -65,7 +65,9 @@ pub fn sh_quote(s: &str) -> String {
|
|||||||
|
|
||||||
/// Render the guest init. The payload runs as a child (never `exec`):
|
/// Render the guest init. The payload runs as a child (never `exec`):
|
||||||
/// the init must outlive it to write the exit code and power the
|
/// the init must outlive it to write the exit code and power the
|
||||||
/// machine off.
|
/// machine off. A share that fails to mount is named on the console
|
||||||
|
/// and ends the init with exit 126: a run without its shares is not
|
||||||
|
/// the run that was asked for.
|
||||||
pub fn init_script(
|
pub fn init_script(
|
||||||
shares: &[GuestShare],
|
shares: &[GuestShare],
|
||||||
payload: &[String],
|
payload: &[String],
|
||||||
@@ -81,11 +83,11 @@ pub fn init_script(
|
|||||||
set -u\n\n\
|
set -u\n\n\
|
||||||
mount_share() {\n\
|
mount_share() {\n\
|
||||||
\x20 tag=\"$1\"; target=\"$2\"; ro=\"$3\"\n\
|
\x20 tag=\"$1\"; target=\"$2\"; ro=\"$3\"\n\
|
||||||
\x20 mkdir -p \"$target\"\n\
|
\x20 mkdir -p \"$target\" || { echo \"ecrou: cannot create share target '$target'\" >&2; exit 126; }\n\
|
||||||
\x20 if [ \"$ro\" = \"ro\" ]; then\n\
|
\x20 if [ \"$ro\" = \"ro\" ]; then\n\
|
||||||
\x20 mount -t virtiofs -o ro \"$tag\" \"$target\"\n\
|
\x20 mount -t virtiofs -o ro \"$tag\" \"$target\" || { echo \"ecrou: failed to mount share '$tag' at '$target' (read-only)\" >&2; exit 126; }\n\
|
||||||
\x20 else\n\
|
\x20 else\n\
|
||||||
\x20 mount -t virtiofs \"$tag\" \"$target\"\n\
|
\x20 mount -t virtiofs \"$tag\" \"$target\" || { echo \"ecrou: failed to mount share '$tag' at '$target'\" >&2; exit 126; }\n\
|
||||||
\x20 fi\n\
|
\x20 fi\n\
|
||||||
}\n\n",
|
}\n\n",
|
||||||
);
|
);
|
||||||
@@ -177,6 +179,18 @@ mod tests {
|
|||||||
assert_eq!(sh_quote("new\nline"), "'new\nline'");
|
assert_eq!(sh_quote("new\nline"), "'new\nline'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn a_failed_share_mount_is_diagnosed_and_fatal() {
|
||||||
|
let script = init_script(&[], &["true".into()], "/", "m", GuestStdio::Console, None);
|
||||||
|
assert!(
|
||||||
|
script.contains("failed to mount share '$tag' at '$target'"),
|
||||||
|
"{script}"
|
||||||
|
);
|
||||||
|
assert!(script.contains("cannot create share target"), "{script}");
|
||||||
|
// The diagnosis ends the init: nothing runs without its shares.
|
||||||
|
assert!(script.contains(">&2; exit 126; }"), "{script}");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn mounts_each_share_with_its_ro_flag() {
|
fn mounts_each_share_with_its_ro_flag() {
|
||||||
let shares = vec![
|
let shares = vec![
|
||||||
|
|||||||
Reference in new issue
Block a user