()
| 1126 | /// so anything that happens before this should be idempotent. |
| 1127 | #[context("Preparing for write")] |
| 1128 | pub(crate) fn prepare_for_write() -> Result<()> { |
| 1129 | use std::sync::atomic::{AtomicBool, Ordering}; |
| 1130 | |
| 1131 | // This is intending to give "at most once" semantics to this |
| 1132 | // function. We should never invoke this from multiple threads |
| 1133 | // at the same time, but verifying "on main thread" is messy. |
| 1134 | // Yes, using SeqCst is likely overkill, but there is nothing perf |
| 1135 | // sensitive about this. |
| 1136 | static ENTERED: AtomicBool = AtomicBool::new(false); |
| 1137 | if ENTERED.load(Ordering::SeqCst) { |
| 1138 | return Ok(()); |
| 1139 | } |
| 1140 | if ostree_ext::container_utils::running_in_container() { |
| 1141 | anyhow::bail!("Detected container; this command requires a booted host system."); |
| 1142 | } |
| 1143 | crate::cli::require_root(false)?; |
| 1144 | ensure_self_unshared_mount_namespace()?; |
| 1145 | if crate::lsm::selinux_enabled()? && !crate::lsm::selinux_ensure_install()? { |
| 1146 | tracing::debug!("Do not have install_t capabilities"); |
| 1147 | } |
| 1148 | ENTERED.store(true, Ordering::SeqCst); |
| 1149 | Ok(()) |
| 1150 | } |
| 1151 | |
| 1152 | /// Implementation of the `bootc upgrade` CLI command. |
| 1153 | #[context("Upgrading")] |
no test coverage detected