From cf02f76f6931d312f89bbc67fbad1c39a37d3de7 Mon Sep 17 00:00:00 2001 From: Li Xi Date: Mon, 15 May 2023 23:12:00 +0800 Subject: [PATCH] LU-9329 utils: add large xattr support for lustre_rsync.c 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 Change-Id: I3ff49721b88dd31aa8af76da8932d5004c82ea09 Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/50997 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Emoly Liu Reviewed-by: Oleg Drokin --- lustre/tests/lustre-rsync-test.sh | 102 +++++++++++++++++++------------------- lustre/utils/lustre_rsync.c | 21 ++++++-- 2 files changed, 68 insertions(+), 55 deletions(-) diff --git a/lustre/tests/lustre-rsync-test.sh b/lustre/tests/lustre-rsync-test.sh index 06c3a21..55eed52 100644 --- a/lustre/tests/lustre-rsync-test.sh +++ b/lustre/tests/lustre-rsync-test.sh @@ -85,21 +85,22 @@ cleanup_src_tgt() { # "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" - touch $tgt + touch $tgt - 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 } check_diff() { @@ -149,38 +150,38 @@ stop_procs() { # 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") @@ -188,18 +189,19 @@ test_1A() { # was test_1 $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 diff --git a/lustre/utils/lustre_rsync.c b/lustre/utils/lustre_rsync.c index b333b77..944ec2e 100644 --- a/lustre/utils/lustre_rsync.c +++ b/lustre/utils/lustre_rsync.c @@ -482,16 +482,27 @@ int lr_copy_xattr(struct lr_info *info) 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; - 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) { -- 1.8.3.1