diff --git a/rpmostree-cxxrs.cxx b/rpmostree-cxxrs.cxx index f237f326d3..3f53d35d09 100644 --- a/rpmostree-cxxrs.cxx +++ b/rpmostree-cxxrs.cxx @@ -2197,8 +2197,8 @@ extern "C" ::rust::repr::PtrLen rpmostreecxx$cxxbridge1$convert_var_to_tmpfiles_d ( ::std::int32_t rootfs_dfd, ::rpmostreecxx::GCancellable const &cancellable) noexcept; - ::rust::repr::PtrLen - rpmostreecxx$cxxbridge1$rootfs_prepare_links (::std::int32_t rootfs_dfd) noexcept; + ::rust::repr::PtrLen rpmostreecxx$cxxbridge1$rootfs_prepare_links (::std::int32_t rootfs_dfd, + bool skip_usrlocal) noexcept; ::rust::repr::PtrLen rpmostreecxx$cxxbridge1$workaround_selinux_cross_labeling ( ::std::int32_t rootfs_dfd, ::rpmostreecxx::GCancellable &cancellable) noexcept; @@ -4032,9 +4032,10 @@ convert_var_to_tmpfiles_d (::std::int32_t rootfs_dfd, } void -rootfs_prepare_links (::std::int32_t rootfs_dfd) +rootfs_prepare_links (::std::int32_t rootfs_dfd, bool skip_usrlocal) { - ::rust::repr::PtrLen error$ = rpmostreecxx$cxxbridge1$rootfs_prepare_links (rootfs_dfd); + ::rust::repr::PtrLen error$ + = rpmostreecxx$cxxbridge1$rootfs_prepare_links (rootfs_dfd, skip_usrlocal); if (error$.ptr) { throw ::rust::impl< ::rust::Error>::error (error$); diff --git a/rpmostree-cxxrs.h b/rpmostree-cxxrs.h index 5ec26d72d0..3798438655 100644 --- a/rpmostree-cxxrs.h +++ b/rpmostree-cxxrs.h @@ -1863,7 +1863,7 @@ void compose_postprocess_final (::std::int32_t rootfs_dfd, void convert_var_to_tmpfiles_d (::std::int32_t rootfs_dfd, ::rpmostreecxx::GCancellable const &cancellable); -void rootfs_prepare_links (::std::int32_t rootfs_dfd); +void rootfs_prepare_links (::std::int32_t rootfs_dfd, bool skip_usrlocal); void workaround_selinux_cross_labeling (::std::int32_t rootfs_dfd, ::rpmostreecxx::GCancellable &cancellable); diff --git a/rust/src/composepost.rs b/rust/src/composepost.rs index e3377d33b5..4d3871be32 100644 --- a/rust/src/composepost.rs +++ b/rust/src/composepost.rs @@ -963,18 +963,20 @@ fn convert_path_to_tmpfiles_d_recurse( /// - If present, symlink /var/lib/alternatives -> /usr/lib/alternatives /// - If present, symlink /var/lib/vagrant -> /usr/lib/vagrant #[context("Preparing symlinks in rootfs")] -pub fn rootfs_prepare_links(rootfs_dfd: i32) -> CxxResult<()> { +pub fn rootfs_prepare_links(rootfs_dfd: i32, skip_usrlocal: bool) -> CxxResult<()> { let rootfs = unsafe { &crate::ffiutil::ffi_dirfd(rootfs_dfd)? }; let mut db = dirbuilder_from_mode(0o755); db.recursive(true); - if !crate::ostree_prepareroot::transient_root_enabled(rootfs)? { - // Unconditionally drop /usr/local and replace it with a symlink. - rootfs - .remove_all_optional("usr/local") - .context("Removing /usr/local")?; - ensure_symlink(rootfs, "../var/usrlocal", "usr/local") - .context("Creating /usr/local symlink")?; + if !skip_usrlocal { + if !crate::ostree_prepareroot::transient_root_enabled(rootfs)? { + // Unconditionally drop /usr/local and replace it with a symlink. + rootfs + .remove_all_optional("usr/local") + .context("Removing /usr/local")?; + ensure_symlink(rootfs, "../var/usrlocal", "usr/local") + .context("Creating /usr/local symlink")?; + } } // Move existing content to /usr/lib, then put a symlink in its @@ -1568,7 +1570,7 @@ OSTREE_VERSION='33.4' rootfs.ensure_dir_with("var/lib/alternatives", &db).unwrap(); rootfs.ensure_dir_with("var/lib/vagrant", &db).unwrap(); - rootfs_prepare_links(rootfs.as_raw_fd()).unwrap(); + rootfs_prepare_links(rootfs.as_raw_fd(), false).unwrap(); { let usr_dir = rootfs.open_dir("usr").unwrap(); let local_target = usr_dir.read_link("local").unwrap(); diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 6ec96d8ff3..6ea5d4df48 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -298,7 +298,7 @@ pub mod ffi { fn compose_postprocess_final_pre(rootfs_dfd: i32) -> Result<()>; fn compose_postprocess_final(rootfs_dfd: i32, treefile: &Treefile) -> Result<()>; fn convert_var_to_tmpfiles_d(rootfs_dfd: i32, cancellable: &GCancellable) -> Result<()>; - fn rootfs_prepare_links(rootfs_dfd: i32) -> Result<()>; + fn rootfs_prepare_links(rootfs_dfd: i32, skip_usrlocal: bool) -> Result<()>; fn workaround_selinux_cross_labeling( rootfs_dfd: i32, cancellable: Pin<&mut GCancellable>, diff --git a/src/libpriv/rpmostree-core.cxx b/src/libpriv/rpmostree-core.cxx index 5ba6ca23b6..552d7d2397 100644 --- a/src/libpriv/rpmostree-core.cxx +++ b/src/libpriv/rpmostree-core.cxx @@ -4287,7 +4287,11 @@ rpmostree_context_assemble (RpmOstreeContext *self, GCancellable *cancellable, G */ if (!glnx_shutil_mkdir_p_at (tmprootfs_dfd, "var/tmp", 0755, cancellable, error)) return FALSE; - ROSCXX_TRY (rootfs_prepare_links (tmprootfs_dfd), error); + /* Note `true` here; this function confusingly creates /usr/local, which is + * under /usr as well as symlinks under /var. We're really interested here + * in the / var part. We don't wnat to change the /usr/local setting from the + * base tree (or in a base compoase, `filesystem`). */ + ROSCXX_TRY (rootfs_prepare_links (tmprootfs_dfd, true), error); CXX_TRY_VAR (etc_guard, rpmostreecxx::prepare_tempetc_guard (tmprootfs_dfd), error); diff --git a/src/libpriv/rpmostree-postprocess.cxx b/src/libpriv/rpmostree-postprocess.cxx index 4904f97e71..be65806ec2 100644 --- a/src/libpriv/rpmostree-postprocess.cxx +++ b/src/libpriv/rpmostree-postprocess.cxx @@ -423,7 +423,7 @@ postprocess_final (int rootfs_dfd, rpmostreecxx::Treefile &treefile, gboolean un return glnx_prefix_error (error, "SELinux postprocess"); } - ROSCXX_TRY (rootfs_prepare_links (rootfs_dfd), error); + ROSCXX_TRY (rootfs_prepare_links (rootfs_dfd, false), error); if (!unified_core_mode) ROSCXX_TRY (convert_var_to_tmpfiles_d (rootfs_dfd, *cancellable), error);