lustre_rsync.c had the problem of not able to get the desired
xattr buffer size, thus is not able to support large xattr
(> PATH_MAX).
lustre-rsync-test:1A would fail if /tmp file system on the
test client supports large xattr.
The following lustre_rsync log shows that lgetxattr keeps
on failing on large xattr (user.foo):
(trusted.lma,
14307984) rc=0x18
lsetxattr(), rc=0, errno=0
(trusted.lov,
14307984) rc=0x38
lsetxattr(), rc=0, errno=0
(trusted.link,
14307984) rc=0x2f
lsetxattr(), rc=0, errno=0
(trusted.som,
14307984) rc=0x18
lsetxattr(), rc=0, errno=0
(user.foo,
14307984) rc=0xffffffff
(lustre.lov,
14307984) rc=0x38
lsetxattr(), rc=-1, errno=95
Test-Parameters: trivial testlist=lustre-rsync-test
Signed-off-by: Li Xi <lixi@ddn.com>
Change-Id: I3ff49721b88dd31aa8af76da8932d5004c82ea09
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/50997
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Emoly Liu <emoly@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
# "small" - large xattr is unsupported but small xattr is supported
# "no" - xattr is unsupported
check_xattr() {
# "small" - large xattr is unsupported but small xattr is supported
# "no" - xattr is unsupported
check_xattr() {
- local tgt=$1
- local xattr="no"
+ local tgt=$1
+ local xattr="no"
- local val="$(generate_string $(max_xattr_size))"
- if large_xattr_enabled &&
- setfattr -n user.foo -v $val $tgt 2>/dev/null; then
- xattr="large"
- else
- setfattr -n user.foo -v bar $tgt 2>/dev/null && xattr="small"
- fi
+ local val="$(generate_string $(max_xattr_size))"
- rm -f $tgt
- echo $xattr
+ if large_xattr_enabled &&
+ setfattr -n user.foo -v $val $tgt 2>/dev/null; then
+ xattr="large"
+ else
+ setfattr -n user.foo -v bar $tgt 2>/dev/null && xattr="small"
+ fi
+
+ rm -f $tgt
+ echo $xattr
# Test 1A - test basic operations
test_1A() { # was test_1
# Test 1A - test basic operations
test_1A() { # was test_1
- init_src
- init_changelog
- local xattr=$(check_xattr $TGT/foo)
+ init_src
+ init_changelog
+ local xattr=$(check_xattr $TGT/foo)
- # Directory create
- mkdir $DIR/$tdir/d1
- mkdir $DIR/$tdir/d2
+ # Directory create
+ mkdir $DIR/$tdir/d1
+ mkdir $DIR/$tdir/d2
- # File create
- touch $DIR/$tdir/file1
- cp /etc/hosts $DIR/$tdir/d1/
- touch $DIR/$tdir/d1/"space in filename"
- touch $DIR/$tdir/d1/file2
+ # File create
+ touch $DIR/$tdir/file1
+ cp /etc/hosts $DIR/$tdir/d1/
+ touch $DIR/$tdir/d1/"space in filename"
+ touch $DIR/$tdir/d1/file2
- # File rename
- mv $DIR/$tdir/d1/file2 $DIR/$tdir/d2/file3
+ # File rename
+ mv $DIR/$tdir/d1/file2 $DIR/$tdir/d2/file3
- # File and directory delete
- touch $DIR/$tdir/d1/file4
- mkdir $DIR/$tdir/d1/del
- touch $DIR/$tdir/d1/del/del1
- touch $DIR/$tdir/d1/del/del2
- rm -rf $DIR/$tdir/d1/del
- rm $DIR/$tdir/d1/file4
+ # File and directory delete
+ touch $DIR/$tdir/d1/file4
+ mkdir $DIR/$tdir/d1/del
+ touch $DIR/$tdir/d1/del/del1
+ touch $DIR/$tdir/d1/del/del2
+ rm -rf $DIR/$tdir/d1/del
+ rm $DIR/$tdir/d1/file4
- #hard and soft links
- cat /etc/hosts > $DIR/$tdir/d1/link1
- ln $DIR/$tdir/d1/link1 $DIR/$tdir/d1/link2
- ln -s $DIR/$tdir/d1/link1 $DIR/$tdir/d1/link3
+ # Hard and soft links
+ cat /etc/hosts > $DIR/$tdir/d1/link1
+ ln $DIR/$tdir/d1/link1 $DIR/$tdir/d1/link2
+ ln -s $DIR/$tdir/d1/link1 $DIR/$tdir/d1/link3
- # Device files
- #mknod $DIR/$tdir/dev1 b 8 1
+ # Device files
+ #mknod $DIR/$tdir/dev1 b 8 1
# Replicate
local LRSYNC_LOG=$(generate_logname "lrsync_log")
# Replicate
local LRSYNC_LOG=$(generate_logname "lrsync_log")
$LRSYNC -s $DIR -t $TGT -t $TGT2 -m $MDT0 -u $CL_USER -l $LREPL_LOG \
-D $LRSYNC_LOG
$LRSYNC -s $DIR -t $TGT -t $TGT2 -m $MDT0 -u $CL_USER -l $LREPL_LOG \
-D $LRSYNC_LOG
- # Set attributes
- chmod 000 $DIR/$tdir/d2/file3
- chown nobody:$GROUP $DIR/$tdir/d2/file3
-
- # Set xattrs
- if [[ "$xattr" != "no" ]]; then
- local value
- touch $DIR/$tdir/file5
- [[ "$xattr" = "large" ]] &&
- value="$(generate_string $(max_xattr_size))" || value="bar"
- setfattr -n user.foo -v $value $DIR/$tdir/file5
- fi
+ # Set attributes
+ chmod 000 $DIR/$tdir/d2/file3
+ chown nobody:$GROUP $DIR/$tdir/d2/file3
+
+ # Set xattrs
+ if [[ "$xattr" != "no" ]]; then
+ local value
+ touch $DIR/$tdir/file5
+ [[ "$xattr" = "large" ]] &&
+ value="$(generate_string $(max_xattr_size))" || value="bar"
+ setfattr -n user.foo -v $value $DIR/$tdir/file5 ||
+ error "setfattr failed"
+ fi
echo "Replication #2"
$LRSYNC -l $LREPL_LOG -D $LRSYNC_LOG
echo "Replication #2"
$LRSYNC -l $LREPL_LOG -D $LRSYNC_LOG
while (start < len) {
size = info->xvsize;
rc = lgetxattr(info->src, info->xlist + start,
while (start < len) {
size = info->xvsize;
rc = lgetxattr(info->src, info->xlist + start,
- info->xvalue, size);
- if (!info->xvalue || errno == ERANGE) {
- size = rc > PATH_MAX ? rc : PATH_MAX;
+ NULL, 0);
+ if (rc < 0) {
+ lr_debug(DTRACE, "\t(%s,0) rc=%d, errno=%d\n",
+ info->xlist + start, rc, errno);
+ start += strlen(info->xlist + start) + 1;
+ continue;
+ }
+ if (rc > size) {
+ /*
+ * XATTR_SIZE_MAX should be the upper limit, but
+ * just in case.
+ */
+ size = rc > XATTR_SIZE_MAX ? rc : XATTR_SIZE_MAX;
info->xvalue = lr_grow_buf(info->xvalue, size);
if (!info->xvalue)
return -ENOMEM;
info->xvsize = size;
info->xvalue = lr_grow_buf(info->xvalue, size);
if (!info->xvalue)
return -ENOMEM;
info->xvsize = size;
- rc = lgetxattr(info->src, info->xlist + start,
- info->xvalue, size);
+
+ rc = lgetxattr(info->src, info->xlist + start,
+ info->xvalue, size);
lr_debug(DTRACE, "\t(%s,%d) rc=%p\n", info->xlist + start,
info->xvalue, rc);
if (rc > 0) {
lr_debug(DTRACE, "\t(%s,%d) rc=%p\n", info->xlist + start,
info->xvalue, rc);
if (rc > 0) {