core: Use DEVINO_CANONICAL for pkglayer if policy unchanged

There's a lot more details in the libostree PR:
https://github.com/ostreedev/ostree/pull/1357

Basically loading the xattrs is slow; let's only do it if we need to, and "need
to" is defined by "SELinux policy changed". On my test F27AH VM, the difference
between a stat() + hash table lookup versus the full xattr load on my test case
of rpm-ostree install ./tree-1.7.0-10.fc27.x86_64.rpm is absolutely dramatic;
consistently on the order of 10s without this support, and <1s with (800ms).

Closes: #1123
Approved by: jlebon
This commit is contained in:
Colin Walters 2017-11-30 21:52:58 -05:00 committed by Atomic Bot
parent fcc30ffe5d
commit dded5c0fdc
2 changed files with 23 additions and 9 deletions

View File

@ -86,7 +86,7 @@ LIBS="$save_LIBS"
# Remember to update AM_CPPFLAGS in Makefile.am when bumping GIO req. # Remember to update AM_CPPFLAGS in Makefile.am when bumping GIO req.
PKG_CHECK_MODULES(PKGDEP_GIO_UNIX, [gio-unix-2.0]) PKG_CHECK_MODULES(PKGDEP_GIO_UNIX, [gio-unix-2.0])
PKG_CHECK_MODULES(PKGDEP_RPMOSTREE, [gio-unix-2.0 >= 2.40.0 json-glib-1.0 PKG_CHECK_MODULES(PKGDEP_RPMOSTREE, [gio-unix-2.0 >= 2.40.0 json-glib-1.0
ostree-1 >= 2017.10 ostree-1 >= 2017.14
libsystemd libsystemd
polkit-gobject-1 polkit-gobject-1
rpm librepo rpm librepo

View File

@ -3640,27 +3640,38 @@ rpmostree_context_commit (RpmOstreeContext *self,
if (ostree_repo_get_mode (self->ostreerepo) == OSTREE_REPO_MODE_BARE_USER_ONLY) if (ostree_repo_get_mode (self->ostreerepo) == OSTREE_REPO_MODE_BARE_USER_ONLY)
modflags |= OSTREE_REPO_COMMIT_MODIFIER_FLAGS_CANONICAL_PERMISSIONS; modflags |= OSTREE_REPO_COMMIT_MODIFIER_FLAGS_CANONICAL_PERMISSIONS;
commit_modifier = ostree_repo_commit_modifier_new (modflags, NULL, NULL, NULL);
if (self->devino_cache)
ostree_repo_commit_modifier_set_devino_cache (commit_modifier, self->devino_cache);
/* if we're SELinux aware, then reload the final policy from the tmprootfs in case it /* if we're SELinux aware, then reload the final policy from the tmprootfs in case it
* was changed by a scriptlet; this covers the foobar/foobar-selinux path */ * was changed by a scriptlet; this covers the foobar/foobar-selinux path */
g_autoptr(OstreeSePolicy) final_sepolicy = NULL;
if (self->sepolicy) if (self->sepolicy)
{ {
g_autoptr(OstreeSePolicy) final_sepolicy = NULL;
if (!rpmostree_prepare_rootfs_get_sepolicy (self->tmprootfs_dfd, &final_sepolicy, if (!rpmostree_prepare_rootfs_get_sepolicy (self->tmprootfs_dfd, &final_sepolicy,
cancellable, error)) cancellable, error))
return FALSE; return FALSE;
/* takes a ref */ /* If policy didn't change (or SELinux is disabled), then we can treat
ostree_repo_commit_modifier_set_sepolicy (commit_modifier, final_sepolicy); * the on-disk xattrs as canonical; loading the xattrs is a noticeable
* slowdown for commit.
*/
if (ostree_sepolicy_get_name (final_sepolicy) == NULL ||
g_strcmp0 (ostree_sepolicy_get_csum (self->sepolicy),
ostree_sepolicy_get_csum (final_sepolicy)) == 0)
{
if (ostree_repo_get_mode (self->ostreerepo) == OSTREE_REPO_MODE_BARE)
modflags |= OSTREE_REPO_COMMIT_MODIFIER_FLAGS_DEVINO_CANONICAL;
}
} }
commit_modifier = ostree_repo_commit_modifier_new (modflags, NULL, NULL, NULL);
if (final_sepolicy)
ostree_repo_commit_modifier_set_sepolicy (commit_modifier, final_sepolicy);
if (self->devino_cache)
ostree_repo_commit_modifier_set_devino_cache (commit_modifier, self->devino_cache);
mtree = ostree_mutable_tree_new (); mtree = ostree_mutable_tree_new ();
const guint64 start_time_ms = g_get_monotonic_time () / 1000;
if (!ostree_repo_write_dfd_to_mtree (self->ostreerepo, self->tmprootfs_dfd, ".", if (!ostree_repo_write_dfd_to_mtree (self->ostreerepo, self->tmprootfs_dfd, ".",
mtree, commit_modifier, mtree, commit_modifier,
cancellable, error)) cancellable, error))
@ -3690,6 +3701,8 @@ rpmostree_context_commit (RpmOstreeContext *self,
return FALSE; return FALSE;
bytes_written_formatted = g_format_size (stats.content_bytes_written); bytes_written_formatted = g_format_size (stats.content_bytes_written);
const guint64 end_time_ms = g_get_monotonic_time () / 1000;
const guint64 elapsed_ms = end_time_ms - start_time_ms;
/* TODO: abstract a variant of this into libglnx which does /* TODO: abstract a variant of this into libglnx which does
* *
@ -3714,6 +3727,7 @@ rpmostree_context_commit (RpmOstreeContext *self,
"OSTREE_METADATA_OBJECTS_WRITTEN=%u", stats.metadata_objects_written, "OSTREE_METADATA_OBJECTS_WRITTEN=%u", stats.metadata_objects_written,
"OSTREE_CONTENT_OBJECTS_WRITTEN=%u", stats.content_objects_written, "OSTREE_CONTENT_OBJECTS_WRITTEN=%u", stats.content_objects_written,
"OSTREE_CONTENT_BYTES_WRITTEN=%" G_GUINT64_FORMAT, stats.content_bytes_written, "OSTREE_CONTENT_BYTES_WRITTEN=%" G_GUINT64_FORMAT, stats.content_bytes_written,
"OSTREE_TXN_ELAPSED_MS=%" G_GUINT64_FORMAT, elapsed_ms,
NULL); NULL);
} }
} }