treecompose: fix crash when "remove-from-packages" used

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.

So we set the symlink now. This is also what we do on boot anyway for
compatibility reasons using tmpfiles.

This also means we don't have to do the /var/lib/rpm --> /usr/share/rpm
transition during the rootfs postprocess (but we still have to clean up
db and lock files).

Also get rid of the unused pkglist variable.

NB: I used the GFile & gs APIs to mesh with the surrounding code.

Closes: #290
Approved by: cgwalters
This commit is contained in:
Jonathan Lebon 2016-05-27 10:46:53 -04:00 committed by Atomic Bot
parent b1bb193871
commit d9e8535bcf
2 changed files with 29 additions and 6 deletions

View File

@ -1131,9 +1131,6 @@ rpmostree_rootfs_postprocess_common (int rootfs_fd,
if (!rename_if_exists (rootfs_fd, "etc", "usr/etc", error))
goto out;
if (!rename_if_exists (rootfs_fd, "var/lib/rpm", "usr/share/rpm", error))
goto out;
if (!glnx_dirfd_iterator_init_at (rootfs_fd, "usr/share/rpm", TRUE, &dfd_iter, error))
{
g_prefix_error (error, "Opening usr/share/rpm: ");
@ -1379,18 +1376,42 @@ rpmostree_treefile_postprocessing (GFile *yumroot,
}
}
/* 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.
* */
{
gs_unref_object GFile *rpmdb =
g_file_resolve_relative_path (yumroot, "var/lib/rpm");
if (g_file_query_exists (rpmdb, NULL))
{
if (!gs_shutil_rm_rf (rpmdb, cancellable, error))
goto out;
}
if (!g_file_make_symbolic_link (rpmdb, "../../usr/share/rpm",
cancellable, error))
goto out;
}
if (json_object_has_member (treefile, "remove-from-packages"))
{
g_autoptr(RpmOstreeRefSack) refsack = NULL;
g_autoptr(GPtrArray) pkglist = NULL;
guint i;
remove = json_object_get_array_member (treefile, "remove-from-packages");
len = json_array_get_length (remove);
if (!rpmostree_get_pkglist_for_root (AT_FDCWD, gs_file_get_path_cached (yumroot),
&refsack, &pkglist,
cancellable, error))
&refsack, NULL, cancellable, error))
{
g_prefix_error (error, "Reading package set: ");
goto out;

View File

@ -21,6 +21,7 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
%install
mkdir -p %{buildroot}/boot
mkdir -p %{buildroot}/var/lib
mkdir -p %{buildroot}/var/share/
mkdir -p %{buildroot}/var/tmp/
mkdir -p %{buildroot}/usr/sbin
@ -46,6 +47,7 @@ touch %{buildroot}/var/tmp/initramfs.img
rm -rf %{buildroot}
%files
/var/lib
/var/share/*
/boot/*
/usr/sbin/*