Commit d724dd18 authored by Wayne Davison's avatar Wayne Davison

Fixed the interaction of --fake-super with --link-dest & --xattrs.

Fixed the munging of non-user namespace xattrs w/--fake-super.
Fixed the sorting of received xattrs when name-munging occurs.
Added xattr tests to verify that these things stay fixed.
parent cbbd8e2e
......@@ -20,6 +20,7 @@ case "`xattr 2>&1`" in
xls() {
xattr -l "${@}"
}
RUSR='rsync'
;;
*)
xset() {
......@@ -31,6 +32,7 @@ case "`xattr 2>&1`" in
xls() {
getfattr -d "${@}"
}
RUSR='user.rsync'
;;
esac
......@@ -65,13 +67,15 @@ xset user.long 'a long attribute for our new file that tests to ensure that this
xset user.foo 'new foo' foo/file3 foo/bar/file5
xset user.bar 'new bar' foo/file3 foo/bar/file5
xset user.long 'this is also a long attribute that will be truncated in the initial data send' foo/file3 foo/bar/file5
xset user.equal 'this long attribute should remain the same and not need to be transferred' foo/file3 foo/bar/file5
xset $RUSR.equal 'this long attribute should remain the same and not need to be transferred' foo/file3 foo/bar/file5
xset $RUSR.equal 'this short' foo/file3 foo/bar/file5
xset user.short 'old short' "$chkdir/file1"
xset user.extra 'remove me' "$chkdir/file1"
xset user.foo 'old foo' "$chkdir/foo/file3"
xset user.equal 'this long attribute should remain the same and not need to be transferred' "$chkdir/foo/file3"
xset $RUSR.equal 'this long attribute should remain the same and not need to be transferred' "$chkdir/foo/file3"
xset $RUSR.equal 'this short' "$chkdir/foo/file3"
xls $files >"$scratchdir/xattrs.txt"
......@@ -95,10 +99,17 @@ xls $files >"$scratchdir/xattrs.txt"
rm -rf "$todir"
checkit "$RSYNC -aiX --link-dest=../chk . ../to" "$chkdir" "$todir"
checkit "$RSYNC -aiX --fake-super --link-dest=../chk . ../to" "$chkdir" "$todir"
cd "$todir"
xls $files | diff $diffopt "$scratchdir/xattrs.txt" -
sed -n -e '/\.\/file1$/d' -e '/^[^ ]* *[^ ]* *[^ ]* *1 /p' "$scratchdir/ls-to" >"$scratchdir/ls-diff"
if [ -s "$scratchdir/ls-diff" ]; then
echo "Missing hard links on:"
cat "$scratchdir/ls-diff"
exit 1
fi
# The script would have aborted on error, so getting here means we've won.
exit 0
......@@ -62,9 +62,12 @@ extern int checksum_seed;
#endif
#define RPRE_LEN ((int)sizeof RSYNC_PREFIX - 1)
#define XSTAT_ATTR RSYNC_PREFIX "%stat"
#define XACC_ACL_ATTR RSYNC_PREFIX "%aacl"
#define XDEF_ACL_ATTR RSYNC_PREFIX "%dacl"
#define XSTAT_SUFFIX "stat"
#define XSTAT_ATTR RSYNC_PREFIX "%" XSTAT_SUFFIX
#define XACC_ACL_SUFFIX "aacl"
#define XACC_ACL_ATTR RSYNC_PREFIX "%" XACC_ACL_SUFFIX
#define XDEF_ACL_SUFFIX "dacl"
#define XDEF_ACL_ATTR RSYNC_PREFIX "%" XDEF_ACL_SUFFIX
typedef struct {
char *datum, *name;
......@@ -231,7 +234,10 @@ static int rsync_xal_get(const char *fname, item_list *xalp)
if (name_len > RPRE_LEN && name[RPRE_LEN] == '%'
&& HAS_PREFIX(name, RSYNC_PREFIX)) {
if ((am_sender && preserve_xattrs < 2)
|| (am_root < 0 && strcmp(name, XSTAT_ATTR) == 0))
|| (am_root < 0
&& (strcmp(name+RPRE_LEN+1, XSTAT_SUFFIX) == 0
|| strcmp(name+RPRE_LEN+1, XACC_ACL_SUFFIX) == 0
|| strcmp(name+RPRE_LEN+1, XDEF_ACL_SUFFIX) == 0)))
continue;
}
......@@ -253,14 +259,6 @@ static int rsync_xal_get(const char *fname, item_list *xalp)
} else
name_offset = datum_len;
#ifdef HAVE_LINUX_XATTRS
if (am_root < 0 && name_len > RPRE_LEN && name[RPRE_LEN] != '%'
&& HAS_PREFIX(name, RSYNC_PREFIX)) {
name += RPRE_LEN;
name_len -= RPRE_LEN;
}
#endif
rxa = EXPAND_ITEM_LIST(xalp, rsync_xa, RSYNC_XAL_INITIAL);
rxa->name = ptr + name_offset;
memcpy(rxa->name, name, name_len);
......@@ -352,25 +350,33 @@ int send_xattr(stat_x *sxp, int f)
int count = sxp->xattr->count;
write_varint(f, count);
for (rxa = sxp->xattr->items; count--; rxa++) {
int name_len = rxa->name_len;
const char *name = rxa->name;
/* Strip the rsync prefix from disguised namespaces. */
if (
#ifdef HAVE_LINUX_XATTRS
write_varint(f, rxa->name_len);
am_root < 0
#endif
&& name_len > RPRE_LEN && name[RPRE_LEN] != '%'
&& HAS_PREFIX(name, RSYNC_PREFIX)) {
name += RPRE_LEN;
name_len -= RPRE_LEN;
}
#ifndef HAVE_LINUX_XATTRS
else {
/* Put everything else in the user namespace. */
name_len += UPRE_LEN;
}
#endif
write_varint(f, name_len);
write_varint(f, rxa->datum_len);
write_buf(f, rxa->name, rxa->name_len);
#else
/* We strip the rsync prefix from disguised namespaces
* and put everything else in the user namespace. */
if (HAS_PREFIX(rxa->name, RSYNC_PREFIX)
&& rxa->name[RPRE_LEN] != '%') {
write_varint(f, rxa->name_len - RPRE_LEN);
write_varint(f, rxa->datum_len);
write_buf(f, rxa->name + RPRE_LEN, rxa->name_len - RPRE_LEN);
} else {
write_varint(f, rxa->name_len + UPRE_LEN);
write_varint(f, rxa->datum_len);
#ifndef HAVE_LINUX_XATTRS
if (name_len > rxa->name_len) {
write_buf(f, USER_PREFIX, UPRE_LEN);
write_buf(f, rxa->name, rxa->name_len);
name_len -= UPRE_LEN;
}
#endif
write_buf(f, name, name_len);
if (rxa->datum_len > MAX_FULL_DATUM)
write_buf(f, rxa->datum + 1, MAX_DIGEST_LEN);
else
......@@ -574,6 +580,11 @@ void receive_xattr(struct file_struct *file, int f)
{
static item_list temp_xattr = EMPTY_ITEM_LIST;
int count, num;
#ifdef HAVE_LINUX_XATTRS
int need_sort = 0;
#else
int need_sort = 1;
#endif
int ndx = read_varint(f);
if (ndx < 0 || (size_t)ndx > rsync_xal_l.count) {
......@@ -624,6 +635,7 @@ void receive_xattr(struct file_struct *file, int f)
name -= RPRE_LEN;
name_len += RPRE_LEN;
memcpy(name, RSYNC_PREFIX, RPRE_LEN);
need_sort = 1;
}
#else
/* This OS only has a user namespace, so we either
......@@ -655,6 +667,9 @@ void receive_xattr(struct file_struct *file, int f)
rxa->num = num;
}
if (need_sort && count > 1)
qsort(temp_xattr.items, count, sizeof (rsync_xa), rsync_xal_compare_names);
ndx = rsync_xal_l.count; /* pre-incremented count */
rsync_xal_store(&temp_xattr); /* adds item to rsync_xal_l */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment