diff --git a/rust/src/composepost.rs b/rust/src/composepost.rs index 45b58d08..e39a5c11 100644 --- a/rust/src/composepost.rs +++ b/rust/src/composepost.rs @@ -23,6 +23,7 @@ use std::path::Path; /* See rpmostree-core.h */ const RPMOSTREE_RPMDB_LOCATION: &str = "usr/share/rpm"; +const TRADITIONAL_RPMDB_LOCATION: &str = "var/lib/rpm"; // rpm-ostree uses /home → /var/home by default as generated by our // rootfs; we don't expect people to change this. Let's be nice @@ -201,6 +202,27 @@ fn compose_postprocess_add_files( Ok(()) } +#[context("Symlinking {}", TRADITIONAL_RPMDB_LOCATION)] +fn compose_postprocess_rpmdb(rootfs_dfd: &openat::Dir) -> Result<()> { + /* This works around a potential issue with libsolv if we go down the + * rpmostree_get_pkglist_for_root() path. Though rpm has been using the + * /usr/share/rpm location (since the RpmOstreeContext set the _dbpath macro), + * the /var/lib/rpm directory will still exist, but be empty. libsolv gets + * confused because it sees the /var/lib/rpm dir and doesn't even try the + * /usr/share/rpm location, and eventually dies when it tries to load the + * data. XXX: should probably send a patch upstream to libsolv. + * + * So we set the symlink now. This is also what we do on boot anyway for + * compatibility reasons using tmpfiles. + * */ + rootfs_dfd.remove_all(TRADITIONAL_RPMDB_LOCATION)?; + rootfs_dfd.symlink( + TRADITIONAL_RPMDB_LOCATION, + format!("../../{}", RPMOSTREE_RPMDB_LOCATION), + )?; + Ok(()) +} + /// Rust portion of rpmostree_treefile_postprocessing() pub(crate) fn compose_postprocess( rootfs_dfd: i32, @@ -211,6 +233,7 @@ pub(crate) fn compose_postprocess( compose_postprocess_add_files(rootfs_dfd, treefile)?; compose_postprocess_scripts(rootfs_dfd, treefile, unified_core)?; + compose_postprocess_rpmdb(rootfs_dfd)?; Ok(()) } diff --git a/src/libpriv/rpmostree-postprocess.cxx b/src/libpriv/rpmostree-postprocess.cxx index 7f43daa4..da2406d0 100644 --- a/src/libpriv/rpmostree-postprocess.cxx +++ b/src/libpriv/rpmostree-postprocess.cxx @@ -1319,22 +1319,6 @@ rpmostree_treefile_postprocessing (int rootfs_fd, return FALSE; } - /* This works around a potential issue with libsolv if we go down the - * rpmostree_get_pkglist_for_root() path. Though rpm has been using the - * /usr/share/rpm location (since the RpmOstreeContext set the _dbpath macro), - * the /var/lib/rpm directory will still exist, but be empty. libsolv gets - * confused because it sees the /var/lib/rpm dir and doesn't even try the - * /usr/share/rpm location, and eventually dies when it tries to load the - * data. XXX: should probably send a patch upstream to libsolv. - * - * So we set the symlink now. This is also what we do on boot anyway for - * compatibility reasons using tmpfiles. - * */ - if (!glnx_shutil_rm_rf_at (rootfs_fd, "var/lib/rpm", cancellable, error)) - return FALSE; - if (symlinkat ("../../" RPMOSTREE_RPMDB_LOCATION, rootfs_fd, "var/lib/rpm") < 0) - return glnx_throw_errno_prefix (error, "symlinkat(%s)", "var/lib/rpm"); - /* Take care of /etc for these bits */ if (!rename_if_exists (rootfs_fd, "usr/etc", rootfs_fd, "etc", error)) return FALSE;