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

Info drop internal xattrs #288

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
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
22 changes: 22 additions & 0 deletions libcomposefs/lcfs-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,27 +48,49 @@ typedef int errint_t;
#define OVERLAY_XATTR_USER_PREFIX "user."
#define OVERLAY_XATTR_TRUSTED_PREFIX "trusted."
#define OVERLAY_XATTR_PARTIAL_PREFIX "overlay."
// trusted.overlay.
#define OVERLAY_XATTR_PREFIX \
OVERLAY_XATTR_TRUSTED_PREFIX OVERLAY_XATTR_PARTIAL_PREFIX
// user.overlay.
#define OVERLAY_XATTR_USERXATTR_PREFIX \
OVERLAY_XATTR_USER_PREFIX OVERLAY_XATTR_PARTIAL_PREFIX
// trusted.overlay.overlay.
#define OVERLAY_XATTR_ESCAPE_PREFIX OVERLAY_XATTR_PREFIX "overlay."
// trusted.overlay.metacopy
#define OVERLAY_XATTR_METACOPY OVERLAY_XATTR_PREFIX "metacopy"
// trusted.overlay.redirect
#define OVERLAY_XATTR_REDIRECT OVERLAY_XATTR_PREFIX "redirect"
// trusted.overlay.whiteout
#define OVERLAY_XATTR_WHITEOUT OVERLAY_XATTR_PREFIX "whiteout"
// trusted.overlay.whiteouts
#define OVERLAY_XATTR_WHITEOUTS OVERLAY_XATTR_PREFIX "whiteouts"
// trusted.overlay.opaque
#define OVERLAY_XATTR_OPAQUE OVERLAY_XATTR_PREFIX "opaque"

// user.overlay.overlay.
#define OVERLAY_XATTR_USERXATTR_ESCAPE_PREFIX \
OVERLAY_XATTR_USERXATTR_PREFIX "overlay."

// trusted.overlay.overlay.whiteout
#define OVERLAY_XATTR_ESCAPED_WHITEOUT OVERLAY_XATTR_ESCAPE_PREFIX "whiteout"
// trusted.overlay.overlay.whiteouts
#define OVERLAY_XATTR_ESCAPED_WHITEOUTS OVERLAY_XATTR_ESCAPE_PREFIX "whiteouts"
// trusted.overlay.overlay.opaque
#define OVERLAY_XATTR_ESCAPED_OPAQUE OVERLAY_XATTR_ESCAPE_PREFIX "opaque"

// user.overlay.whiteout
#define OVERLAY_XATTR_USERXATTR_WHITEOUT \
OVERLAY_XATTR_USERXATTR_PREFIX "whiteout"
// user.overlay.whiteouts
#define OVERLAY_XATTR_USERXATTR_WHITEOUTS \
OVERLAY_XATTR_USERXATTR_PREFIX "whiteouts"
// user.overlay.opaque
#define OVERLAY_XATTR_USERXATTR_OPAQUE OVERLAY_XATTR_USERXATTR_PREFIX "opaque"

// user.overlay.overlay.opaque
#define OVERLAY_XATTR_USERXATTR_ESCAPED_OPAQUE \
OVERLAY_XATTR_USERXATTR_ESCAPE_PREFIX "opaque"

#define ALIGN_TO(_offset, _align_size) \
(((_offset) + _align_size - 1) & ~(_align_size - 1))

Expand Down
19 changes: 17 additions & 2 deletions libcomposefs/lcfs-writer-erofs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1150,14 +1150,17 @@ static int add_overlayfs_xattrs(struct lcfs_ctx_s *ctx, struct lcfs_node_s *node
if (ret < 0)
return ret;

/* Mark dir containing whiteouts with new format as of version 1 */
/* Mark dir containing whiteouts with new format as of version 1;
* note the code in composefs-info.c which explicitly skips these.
*/
if (ctx->options->version >= 1) {
ret = lcfs_node_set_xattr(
parent, OVERLAY_XATTR_ESCAPED_OPAQUE, "x", 1);
if (ret < 0)
return ret;
ret = lcfs_node_set_xattr(
parent, OVERLAY_XATTR_USERXATTR_OPAQUE, "x", 1);
parent, OVERLAY_XATTR_USERXATTR_ESCAPED_OPAQUE,
"x", 1);
if (ret < 0)
return ret;
}
Expand Down Expand Up @@ -1522,6 +1525,7 @@ static int erofs_readdir_block(struct lcfs_image_data *data,
return 0;
}

// Convert an EROFS entry back into a composefs node.
static int lcfs_build_node_erofs_xattr(struct lcfs_node_s *node, uint8_t name_index,
const char *entry_name, uint8_t name_len,
const char *value, uint16_t value_size)
Expand Down Expand Up @@ -1579,6 +1583,17 @@ static int lcfs_build_node_erofs_xattr(struct lcfs_node_s *node, uint8_t name_in
return 0;
}
}
if (str_has_prefix(name, OVERLAY_XATTR_USERXATTR_PREFIX)) {
if (str_has_prefix(name, OVERLAY_XATTR_USERXATTR_ESCAPE_PREFIX)) {
/* Unescape */
memmove(name + strlen(OVERLAY_XATTR_USER_PREFIX),
name + strlen(OVERLAY_XATTR_USERXATTR_PREFIX),
strlen(name) - strlen(OVERLAY_XATTR_USER_PREFIX) + 1);
} else {
/* skip */
return 0;
}
}

if (lcfs_node_set_xattr(node, name, value, value_size) < 0)
return -1;
Expand Down
18 changes: 17 additions & 1 deletion tests/test-units.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,22 @@ function countobjects () {
find $dir/objects -type f | wc -l
}

# Test a full cycle of roundtrips through mkcomposefs --from-file, composefs-info dump, etc.
function test_dump_roundtrip () {
testsrcdir=$(cd $(dirname $0) && pwd)
pushd $1
local src=$testsrcdir/assets/special.dump
set -x
$BINDIR/mkcomposefs --from-file "${src}" out.cfs
$BINDIR/composefs-info dump out.cfs > dump.txt
diff -u "${src}" dump.txt || exit 1
$BINDIR/mkcomposefs --from-file dump.txt out2.cfs
diff -u out.cfs out2.cfs || exit 1
echo "ok dump roundtrip"
popd
}


# Ensure small files are inlined
function test_inline () {
local dir=$1
Expand Down Expand Up @@ -86,7 +102,7 @@ function test_composefs_info_measure_files () {
cd -
}

TESTS="test_inline test_objects test_mount_digest test_composefs_info_measure_files"
TESTS="test_dump_roundtrip test_inline test_objects test_mount_digest test_composefs_info_measure_files"
res=0
for i in $TESTS; do
testdir=$(mktemp -d $workdir/$i.XXXXXX)
Expand Down
16 changes: 16 additions & 0 deletions tools/composefs-info.c
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,22 @@ static void dump_node(struct lcfs_node_s *node, char *path)
size_t value_len;
const char *value = lcfs_node_get_xattr(target, name, &value_len);

// Skip the special xattrs injected by lcfs-writer-erofs.c to
// denote a directory containing whiteouts.
bool is_opaque_flag =
(strcmp(name, OVERLAY_XATTR_OPAQUE) == 0) ||
(strcmp(name, OVERLAY_XATTR_USERXATTR_OPAQUE) == 0);
bool is_special_x = value_len == 1 && *value == 'x';
if (is_opaque_flag && is_special_x) {
continue;
}

// Undo the effect of the escaping in add_overlayfs_xattrs
if (str_has_prefix(name, OVERLAY_XATTR_ESCAPE_PREFIX)) {
name += strlen(OVERLAY_XATTR_ESCAPE_PREFIX);
} else if (str_has_prefix(name, OVERLAY_XATTR_USERXATTR_ESCAPE_PREFIX)) {
name += strlen(OVERLAY_XATTR_USERXATTR_ESCAPE_PREFIX);
}
printf(" ");
print_escaped(name, -1, ESCAPE_EQUAL);
printf("=");
Expand Down
Loading