Skip to content

Commit

Permalink
Support overlayfs whiteouts on checkout
Browse files Browse the repository at this point in the history
Introduces an intermediate format for overlayfs storage, where
.wh-ostree. prefixed files will be converted into char 0:0
whiteout devices used by overlayfs to mark deletions across layers.

Related-Issue: ostreedev#2712
  • Loading branch information
mangelajo committed Sep 19, 2022
1 parent c6c3c5a commit 2276147
Showing 1 changed file with 31 additions and 1 deletion.
32 changes: 31 additions & 1 deletion src/libostree/ostree-repo-checkout.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
#define WHITEOUT_PREFIX ".wh."
#define OPAQUE_WHITEOUT_NAME ".wh..wh..opq"

#define OVERLAYFS_WHITEOUT_PREFIX ".wh-ostree."

/* Per-checkout call state/caching */
typedef struct {
GString *path_buf; /* buffer for real path if filtering enabled */
Expand Down Expand Up @@ -603,7 +605,8 @@ checkout_one_file_at (OstreeRepo *repo,

/* FIXME - avoid the GFileInfo here */
g_autoptr(GFileInfo) source_info = NULL;
if (!ostree_repo_load_file (repo, checksum, NULL, &source_info, NULL,
g_autoptr(GVariant) source_xattrs = NULL;
if (!ostree_repo_load_file (repo, checksum, NULL, &source_info, &source_xattrs,
cancellable, error))
return FALSE;

Expand All @@ -623,6 +626,7 @@ checkout_one_file_at (OstreeRepo *repo,
const gboolean is_unreadable = (!is_symlink && (source_mode & S_IRUSR) == 0);
const gboolean is_whiteout = (!is_symlink && options->process_whiteouts &&
g_str_has_prefix (destination_name, WHITEOUT_PREFIX));
const gboolean is_overlayfs_whiteout = (!is_symlink && g_str_has_prefix (destination_name, OVERLAYFS_WHITEOUT_PREFIX));
const gboolean is_reg_zerosized = (!is_symlink && g_file_info_get_size (source_info) == 0);
const gboolean override_user_unreadable = (options->mode == OSTREE_REPO_CHECKOUT_MODE_USER && is_unreadable);

Expand All @@ -643,6 +647,32 @@ checkout_one_file_at (OstreeRepo *repo,

need_copy = FALSE;
}
else if (is_overlayfs_whiteout)
{
const char *name = destination_name + (sizeof (OVERLAYFS_WHITEOUT_PREFIX) - 1);

if (!name[0])
return glnx_throw (error, "Invalid empty overlayfs whiteout '%s'", name);

g_assert (name[0] != '/'); /* Sanity */

if (mknodat(destination_dfd, name, (source_mode & ~S_IFMT) | S_IFCHR, (dev_t)0) < 0)
return glnx_throw_errno_prefix (error, "Creating whiteout char device");
if (options->mode != OSTREE_REPO_CHECKOUT_MODE_USER)
{
if (source_xattrs != NULL &&
!glnx_dfd_name_set_all_xattrs(destination_dfd, name, source_xattrs,
cancellable, error))
return glnx_throw_errno_prefix (error, "Setting xattrs for whiteout char device");

if (TEMP_FAILURE_RETRY(fchownat(destination_dfd, name,
g_file_info_get_attribute_uint32 (source_info, "unix::uid"),
g_file_info_get_attribute_uint32 (source_info, "unix::gid"),
AT_SYMLINK_NOFOLLOW) < 0))
return glnx_throw_errno_prefix (error, "fchownat");
}
need_copy = FALSE;
}
else if (is_reg_zerosized || override_user_unreadable)
{
/* In https://github.com/ostreedev/ostree/commit/673cacd633f9d6b653cdea530657d3e780a41bbd we
Expand Down

0 comments on commit 2276147

Please sign in to comment.