deb: make apt wait for the shared archives lock
The shared apt download cache is bind-mounted from outside the chroot, so when an apt of ANOTHER build holds the archives lock from its own pid namespace, a concurrent build's apt sees the holder as "process 0", cannot wait for it, and fails the build immediately (observed as an e2e samba essentials install racing a kernel build's build-deps transaction on the stonking-amd64 cache). Set DPkg::Lock::Timeout to ten minutes in the shared-cache apt conf: apt then waits for the holder instead of erroring. pkh itself already serializes builds per cache with a host-side flock; the timeout covers the window where a killed run's orphaned apt is still winding down.
This commit is contained in:
+13
-3
@@ -320,7 +320,12 @@ pub(crate) fn write_apt_keep_conf(chroot_path: &Path) -> std::io::Result<()> {
|
|||||||
fs::create_dir_all(&conf_dir)?;
|
fs::create_dir_all(&conf_dir)?;
|
||||||
fs::write(
|
fs::write(
|
||||||
conf_dir.join(APT_KEEP_CONF),
|
conf_dir.join(APT_KEEP_CONF),
|
||||||
"APT::Keep-Downloaded-Packages \"true\";\n",
|
// The lock timeout: the shared download cache is bind-mounted
|
||||||
|
// from outside the chroot, so an apt holding the archives lock
|
||||||
|
// in ANOTHER build's pid namespace shows up as "held by process
|
||||||
|
// 0" — a holder apt cannot see or wait for. Wait up to ten
|
||||||
|
// minutes instead of failing the build.
|
||||||
|
"APT::Keep-Downloaded-Packages \"true\";\nDPkg::Lock::Timeout \"600\";\n",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1593,7 +1598,9 @@ mod chroot_cleanup_tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The apt configuration keeping downloaded packages lands in the
|
/// The apt configuration keeping downloaded packages lands in the
|
||||||
/// chroot's apt.conf.d, so installs populate the shared cache.
|
/// chroot's apt.conf.d, so installs populate the shared cache; the
|
||||||
|
/// lock timeout makes apt wait for the shared archives lock instead
|
||||||
|
/// of failing on a holder in another pid namespace.
|
||||||
#[test]
|
#[test]
|
||||||
fn apt_keep_conf_lands_in_the_chroot() {
|
fn apt_keep_conf_lands_in_the_chroot() {
|
||||||
let dir = tempfile::tempdir().unwrap();
|
let dir = tempfile::tempdir().unwrap();
|
||||||
@@ -1601,7 +1608,10 @@ mod chroot_cleanup_tests {
|
|||||||
write_apt_keep_conf(&chroot).unwrap();
|
write_apt_keep_conf(&chroot).unwrap();
|
||||||
let conf = chroot.join("etc/apt/apt.conf.d").join(APT_KEEP_CONF);
|
let conf = chroot.join("etc/apt/apt.conf.d").join(APT_KEEP_CONF);
|
||||||
let content = fs::read_to_string(&conf).unwrap();
|
let content = fs::read_to_string(&conf).unwrap();
|
||||||
assert_eq!(content, "APT::Keep-Downloaded-Packages \"true\";\n");
|
assert_eq!(
|
||||||
|
content,
|
||||||
|
"APT::Keep-Downloaded-Packages \"true\";\nDPkg::Lock::Timeout \"600\";\n"
|
||||||
|
);
|
||||||
|
|
||||||
// Idempotent: a second write does not fail or duplicate.
|
// Idempotent: a second write does not fail or duplicate.
|
||||||
write_apt_keep_conf(&chroot).unwrap();
|
write_apt_keep_conf(&chroot).unwrap();
|
||||||
|
|||||||
Reference in New Issue
Block a user