libpriv/postprocess: also delete semanage lock files
We don't need those in the tree, so let's nuke them. This also fixes subtle compatibility issues between hardlinks and lock files (see #999). Closes: #1002 Approved by: cgwalters
This commit is contained in:
parent
25ba196c27
commit
f089b8de1f
@ -1111,6 +1111,86 @@ rpmostree_rootfs_prepare_links (int rootfs_fd,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
cleanup_leftover_files (int rootfs_fd,
|
||||
const char *subpath,
|
||||
const char *files[],
|
||||
const char *prefixes[],
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
g_auto(GLnxDirFdIterator) dfd_iter = { 0, };
|
||||
if (!glnx_dirfd_iterator_init_at (rootfs_fd, subpath, TRUE, &dfd_iter, error))
|
||||
return glnx_prefix_error (error, "Opening %s", subpath);
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
struct dirent *dent = NULL;
|
||||
if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&dfd_iter, &dent, cancellable, error))
|
||||
return FALSE;
|
||||
if (!dent)
|
||||
break;
|
||||
if (dent->d_type != DT_REG)
|
||||
continue;
|
||||
|
||||
const char *name = dent->d_name;
|
||||
|
||||
const gboolean in_files = (files != NULL && g_strv_contains (files, name));
|
||||
const gboolean has_prefix =
|
||||
(prefixes != NULL && rpmostree_str_has_prefix_in_strv (name, (char**)prefixes, -1));
|
||||
|
||||
if (!in_files && !has_prefix)
|
||||
continue;
|
||||
|
||||
if (unlinkat (dfd_iter.fd, name, 0) < 0)
|
||||
return glnx_throw_errno_prefix (error, "Unlinking %s: ", name);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static const char *selinux_leftover_files[] = { "semanage.trans.LOCK",
|
||||
"semanage.read.LOCK", NULL };
|
||||
static const char *rpmdb_leftover_files[] = { ".dbenv.lock",
|
||||
".rpm.lock", NULL };
|
||||
static const char *rpmdb_leftover_prefixes[] = { "__db.", NULL };
|
||||
|
||||
static gboolean
|
||||
cleanup_selinux_lockfiles (int rootfs_fd,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
struct stat stbuf;
|
||||
if (!glnx_fstatat_allow_noent (rootfs_fd, "usr/etc/selinux", &stbuf, 0, error))
|
||||
return FALSE;
|
||||
|
||||
if (errno == ENOENT)
|
||||
return TRUE; /* Note early return */
|
||||
|
||||
/* really we only have to do this for the active policy, but let's scan all the dirs */
|
||||
g_auto(GLnxDirFdIterator) dfd_iter = { 0, };
|
||||
if (!glnx_dirfd_iterator_init_at (rootfs_fd, "usr/etc/selinux", FALSE, &dfd_iter, error))
|
||||
return glnx_prefix_error (error, "Opening /usr/etc/selinux");
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
struct dirent *dent = NULL;
|
||||
if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&dfd_iter, &dent, cancellable, error))
|
||||
return FALSE;
|
||||
if (!dent)
|
||||
break;
|
||||
if (dent->d_type != DT_DIR)
|
||||
continue;
|
||||
|
||||
const char *name = dent->d_name;
|
||||
if (!cleanup_leftover_files (dfd_iter.fd, name, selinux_leftover_files, NULL,
|
||||
cancellable, error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* rpmostree_rootfs_postprocess_common:
|
||||
*
|
||||
@ -1129,32 +1209,12 @@ rpmostree_rootfs_postprocess_common (int rootfs_fd,
|
||||
if (!rename_if_exists (rootfs_fd, "etc", "usr/etc", error))
|
||||
return FALSE;
|
||||
|
||||
g_auto(GLnxDirFdIterator) dfd_iter = { 0, };
|
||||
if (!glnx_dirfd_iterator_init_at (rootfs_fd, "usr/share/rpm", TRUE, &dfd_iter, error))
|
||||
return glnx_prefix_error (error, "Opening usr/share/rpm");
|
||||
if (!cleanup_leftover_files (rootfs_fd, "usr/share/rpm", rpmdb_leftover_files,
|
||||
rpmdb_leftover_prefixes, cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
struct dirent *dent = NULL;
|
||||
const char *name;
|
||||
|
||||
if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&dfd_iter, &dent, cancellable, error))
|
||||
return FALSE;
|
||||
if (!dent)
|
||||
break;
|
||||
if (dent->d_type != DT_REG)
|
||||
continue;
|
||||
|
||||
name = dent->d_name;
|
||||
|
||||
if (!(g_str_has_prefix (name, "__db.") ||
|
||||
strcmp (name, ".dbenv.lock") == 0 ||
|
||||
strcmp (name, ".rpm.lock") == 0))
|
||||
continue;
|
||||
|
||||
if (unlinkat (dfd_iter.fd, name, 0) < 0)
|
||||
return glnx_throw_errno_prefix (error, "Unlinking %s: ", name);
|
||||
}
|
||||
if (!cleanup_selinux_lockfiles (rootfs_fd, cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
if (!rpmostree_passwd_cleanup (rootfs_fd, cancellable, error))
|
||||
return FALSE;
|
||||
|
@ -371,18 +371,27 @@ rpmostree_file_get_path_cached (GFile *file)
|
||||
}
|
||||
|
||||
gboolean
|
||||
rpmostree_str_has_prefix_in_ptrarray (const char *str,
|
||||
GPtrArray *prefixes)
|
||||
rpmostree_str_has_prefix_in_strv (const char *str,
|
||||
char **prefixes,
|
||||
int n)
|
||||
{
|
||||
for (guint j = 0; j < prefixes->len; j++)
|
||||
if (n < 0)
|
||||
n = g_strv_length (prefixes);
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
const char *prefix = prefixes->pdata[j];
|
||||
if (g_str_has_prefix (str, prefix))
|
||||
if (g_str_has_prefix (str, prefixes[i]))
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
rpmostree_str_has_prefix_in_ptrarray (const char *str,
|
||||
GPtrArray *prefixes)
|
||||
{
|
||||
return rpmostree_str_has_prefix_in_strv (str, (char**)prefixes->pdata, prefixes->len);
|
||||
}
|
||||
|
||||
/* Like g_strv_contains() but for ptrarray */
|
||||
gboolean
|
||||
rpmostree_str_ptrarray_contains (GPtrArray *strs,
|
||||
|
@ -89,6 +89,11 @@ void rpmostree_diff_print (OstreeRepo *repo,
|
||||
GPtrArray *modified_old,
|
||||
GPtrArray *modified_new);
|
||||
|
||||
gboolean
|
||||
rpmostree_str_has_prefix_in_strv (const char *str,
|
||||
char **strv,
|
||||
int n);
|
||||
|
||||
gboolean
|
||||
rpmostree_str_has_prefix_in_ptrarray (const char *str,
|
||||
GPtrArray *prefixes);
|
||||
|
@ -48,3 +48,8 @@ ostree --repo=${repobuild} ls ${treeref} /tmp > ls.txt
|
||||
assert_file_has_content ls.txt 'l00777 0 0 0 /tmp -> sysroot/tmp'
|
||||
echo "ok /tmp"
|
||||
|
||||
ostree --repo=${repobuild} ls ${treeref} /usr/share/rpm > ls.txt
|
||||
assert_not_file_has_content ls.txt '__db' 'lock'
|
||||
ostree --repo=${repobuild} ls -R ${treeref} /usr/etc/selinux > ls.txt
|
||||
assert_not_file_has_content ls.txt 'LOCK'
|
||||
echo "ok no leftover files"
|
||||
|
@ -55,6 +55,10 @@ if ! ostree commit --help | grep -q -e --selinux-policy; then
|
||||
fi
|
||||
# ✀✀✀ END hack to get --selinux-policy ✀✀✀
|
||||
|
||||
# ✀✀✀ BEGIN tmp hack for https://github.com/projectatomic/rpm-ostree/pull/999
|
||||
rm -vrf vmcheck/usr/etc/selinux/targeted/semanage.*.LOCK
|
||||
# ✀✀✀ END tmp hack
|
||||
|
||||
ostree refs --delete vmcheck || true
|
||||
ostree commit -b vmcheck --link-checkout-speedup \
|
||||
--selinux-policy=vmcheck --tree=dir=vmcheck
|
||||
|
Loading…
Reference in New Issue
Block a user