-
Notifications
You must be signed in to change notification settings - Fork 175
upgrade: Add pre-flight disk space check #1995
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,6 +21,7 @@ use ostree_ext::ostree::Deployment; | |
| use ostree_ext::ostree::{self, Sysroot}; | ||
| use ostree_ext::sysroot::SysrootLock; | ||
| use ostree_ext::tokio_util::spawn_blocking_cancellable_flatten; | ||
| use std::os::fd::AsFd; | ||
|
|
||
| use crate::progress_jsonl::{Event, ProgressWriter, SubTaskBytes, SubTaskStep}; | ||
| use crate::spec::ImageReference; | ||
|
|
@@ -361,6 +362,31 @@ pub(crate) async fn prune_container_store(sysroot: &Storage) -> Result<()> { | |
| Ok(()) | ||
| } | ||
|
|
||
| /// Verify there is sufficient disk space to pull an image. | ||
| /// | ||
| /// This checks the available space on the filesystem containing the OSTree repository | ||
| /// against the number of bytes that need to be fetched for the image. | ||
| pub(crate) fn check_disk_space( | ||
| repo_fd: impl AsFd, | ||
| image_meta: &PreparedImportMeta, | ||
| imgref: &ImageReference, | ||
| ) -> Result<()> { | ||
| let stat = rustix::fs::fstatvfs(repo_fd)?; | ||
| let bytes_avail: u64 = stat.f_bsize * stat.f_bavail; | ||
| tracing::trace!("bytes_avail: {bytes_avail}"); | ||
|
|
||
| if image_meta.bytes_to_fetch > bytes_avail { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note that ostree has a slightly stricter check and has a configurable I'm OK with this as is, but how about just a |
||
| anyhow::bail!( | ||
| "Insufficient free space for {image} (available: {bytes_avail} required: {bytes_to_fetch})", | ||
| bytes_avail = ostree_ext::glib::format_size(bytes_avail), | ||
| bytes_to_fetch = ostree_ext::glib::format_size(image_meta.bytes_to_fetch), | ||
| image = imgref.image, | ||
| ); | ||
| } | ||
|
|
||
| Ok(()) | ||
| } | ||
|
|
||
| pub(crate) struct PreparedImportMeta { | ||
| pub imp: ImageImporter, | ||
| pub prep: Box<PreparedImport>, | ||
|
|
@@ -658,6 +684,9 @@ pub(crate) async fn pull( | |
| Ok(existing) | ||
| } | ||
| PreparedPullResult::Ready(prepared_image_meta) => { | ||
| // Check disk space before attempting to pull | ||
| check_disk_space(repo.dfd_borrow(), &prepared_image_meta, imgref)?; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One thing of course here is this doesn't apply to the composefs backend. Hmm, I wonder if container-libs has a similar check? If we get to #20 then the check would need to be there. |
||
|
|
||
| // Log that we're pulling a new image | ||
| const PULLING_NEW_IMAGE_ID: &str = "6d5e4f3a2b1c0d9e8f7a6b5c4d3e2f1a0"; | ||
| tracing::info!( | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The multiplication
stat.f_bsize * stat.f_bavailcould overflow on very large filesystems, as both operands areu64. This would cause a panic in debug builds or wrap around in release builds, leading to incorrect disk space checks. Usingchecked_mul()prevents this by saturating atu64::MAXon overflow, which is a safe upper bound for available space.