Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

checkout: honor opaque checkouts #1486

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions src/libostree/ostree-repo-checkout.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "ostree-repo-private.h"

#define WHITEOUT_PREFIX ".wh."
#define OPAQUE_WHITEOUT_NAME ".wh..wh..opq"

/* Per-checkout call state/caching */
typedef struct {
Expand Down Expand Up @@ -879,6 +880,7 @@ checkout_tree_at_recurse (OstreeRepo *self,
GError **error)
{
gboolean did_exist = FALSE;
gboolean is_opaque_whiteout = FALSE;
const gboolean sepolicy_enabled = options->sepolicy && !self->disable_xattrs;
g_autoptr(GVariant) dirtree = NULL;
g_autoptr(GVariant) dirmeta = NULL;
Expand Down Expand Up @@ -912,6 +914,22 @@ checkout_tree_at_recurse (OstreeRepo *self,
return TRUE; /* Note early return */
}

if (options->process_whiteouts)
{
g_autoptr(GVariant) dir_file_contents = g_variant_get_child_value (dirtree, 0);
GVariantIter viter;
const char *fname;
g_autoptr(GVariant) contents_csum_v = NULL;
g_variant_iter_init (&viter, dir_file_contents);
while (g_variant_iter_loop (&viter, "(&s@ay)", &fname, &contents_csum_v))
{
is_opaque_whiteout = (g_str_equal (fname, OPAQUE_WHITEOUT_NAME));
if (is_opaque_whiteout)
break;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing I don't quite understand is why we're looping over all of the children here. Doesn't there need to be name matching against the target somehow? Or hmm...is the serialization that there's exactly one child with that name?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am looking for a child ".wh..wh..opq" and it needs to have exactly that name. I didn't find a better way for having this search in O(1). Is there a better way to look for it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am looking for a child ".wh..wh..opq" and it needs to have exactly that name.

My question is - should that be the only child?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, there can be other children and they will appear normally in the directory. The ".wh..wh..opq" file is only to hide anything that is in the lower layers, but the same layer can add more content

}
contents_csum_v = NULL; /* iter_loop freed it */
}

/* First, make the directory. Push a new scope in case we end up using
* setfscreatecon().
*/
Expand All @@ -931,6 +949,13 @@ checkout_tree_at_recurse (OstreeRepo *self,
return FALSE;
}

/* If it is an opaque whiteout, ensure the destination is empty first. */
if (is_opaque_whiteout)
{
if (!glnx_shutil_rm_rf_at (destination_parent_fd, destination_name, cancellable, error))
return FALSE;
}

/* Create initially with mode 0700, then chown/chmod only when we're
* done. This avoids anyone else being able to operate on partially
* constructed dirs.
Expand Down
3 changes: 2 additions & 1 deletion tests/basic-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1034,7 +1034,7 @@ echo "ok test error pre commit/bootid"
# Whiteouts
cd ${test_tmpdir}
mkdir -p overlay/baz/
if touch overlay/baz/.wh.cow && touch overlay/.wh.deeper; then
if touch overlay/baz/.wh.cow && touch overlay/.wh.deeper && touch overlay/baz/another/.wh..wh..opq; then
touch overlay/anewfile
mkdir overlay/anewdir/
touch overlay/anewdir/blah
Expand All @@ -1050,6 +1050,7 @@ if touch overlay/baz/.wh.cow && touch overlay/.wh.deeper; then
assert_not_has_dir overlay-co/deeper
assert_has_file overlay-co/anewdir/blah
assert_has_file overlay-co/anewfile
assert_not_has_file overlay-co/baz/another/y

# And test replacing a directory wholesale with a symlink as well as a regular file
mkdir overlay
Expand Down