Whamcloud - gitweb
LU-16331 utils: fix 'lfs find -O <uuid>' with gaps 07/49207/8
authorAndreas Dilger <adilger@whamcloud.com>
Tue, 22 Nov 2022 05:40:03 +0000 (22:40 -0700)
committerOleg Drokin <green@whamcloud.com>
Fri, 19 May 2023 07:04:14 +0000 (07:04 +0000)
Fix the UUID parsing in llapi_get_target_uuids() so that the OST
UUIDs are put into the right slots when there is a gap in numbering.
Otherwise, "lfs find -O <uuid>" will not be able to find the given
UUID if it is the first OST after the gap.

Add test case for 'lfs find' and 'lfs getstripe' with large/sparse
OST indices in conf-sanity test_81.

Test-Parameters: trivial testlist=conf-sanity env=ONLY="81-82"
Signed-off-by: Andreas Dilger <adilger@whamcloud.com>
Change-Id: Ia0581f85f016c202514148114924509118a0f792
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/49207
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Jian Yu <yujian@whamcloud.com>
Reviewed-by: Feng Lei <flei@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/tests/conf-sanity.sh
lustre/utils/liblustreapi.c

index ba1e892..5a6bc4c 100644 (file)
@@ -6442,7 +6442,7 @@ save_ostindex() {
 
        local i
        local index
-       for i in $(seq $OSTCOUNT); do
+       for ((i = 1; i <= $OSTCOUNT; i++ )); do
                index=OSTINDEX$i
                eval saved_ostindex$i=${!index}
                eval OSTINDEX$i=""
@@ -6451,11 +6451,12 @@ save_ostindex() {
 
 # Restore the original values of $OSTCOUNT and $OSTINDEX$i.
 restore_ostindex() {
-       trap 0
-
        local i
        local index
-       for i in $(seq $OSTCOUNT); do
+
+       echo "restoring OSTCOUNT=$saved_ostcount and OSTINDEXn"
+
+       for ((i = 1; i <= $OSTCOUNT; i++ )); do
                index=saved_ostindex$i
                eval OSTINDEX$i=${!index}
        done
@@ -6471,9 +6472,9 @@ restore_ostindex() {
 # expected. This test uses OST_INDEX_LIST to format OSTs with a randomly
 # assigned index and ensures we can mount such a formatted file system
 test_81() { # LU-4665
-       [[ "$MDS1_VERSION" -ge $(version_code 2.6.54) ]] ||
+       (( MDS1_VERSION >= $(version_code 2.6.54) )) ||
                skip "Need MDS version at least 2.6.54"
-       [[ $OSTCOUNT -ge 3 ]] || skip_env "needs >= 3 OSTs"
+       (( OSTCOUNT >= 3 )) || skip_env "needs >= 3 OSTs"
 
        stopall
 
@@ -6493,36 +6494,66 @@ test_81() { # LU-4665
        OSTINDEX1=$saved_ostindex1
 
        save_ostindex 3
+       stack_trap restore_ostindex
 
        # Format OSTs with random sparse indices.
-       trap "restore_ostindex" EXIT
-       echo -e "\nFormat $OSTCOUNT OSTs with sparse indices"
-       OST_INDEX_LIST=[0,$((RANDOM * 2 % 65533 + 1)),65534] formatall
+       local rand_ost=$(((RANDOM * 2 % 65533) + 1))
+       echo  "Format $OSTCOUNT OSTs with OST_INDEX_LIST=[0,$rand_ost,65534]"
+       OST_INDEX_LIST=[0,$rand_ost,65534] formatall ||
+               error "formatall failed with $?"
 
        # Setup and check Lustre filesystem.
        start_mgsmds || error "start_mgsmds failed"
-       for i in $(seq $OSTCOUNT); do
+       for ((i = 1; i <= $OSTCOUNT; i++ )); do
                start ost$i $(ostdevname $i) $OST_MOUNT_OPTS ||
                        error "start ost$i failed"
        done
 
        mount_client $MOUNT || error "mount client $MOUNT failed"
        check_mount || error "check client $MOUNT failed"
+       $LFS df
 
        # Check max_easize.
        local max_easize=$($LCTL get_param -n llite.*.max_easize)
-       # 65452 is XATTR_SIZE_MAX less ldiskfs ea overhead
-       if large_xattr_enabled; then
-               [[ $max_easize -ge 65452 ]] ||
-                       error "max_easize is $max_easize, should be at least 65452 bytes"
-       else
-               # LU-11868
-               # 4012 is 4096 less ldiskfs ea overhead
-               [[ $max_easize -ge 4012 ]] ||
-                       error "max_easize is $max_easize, should be at least 4012 bytes"
-       fi
+       local xattr_size_max=$((4096 - 84)) # 4096 less ldiskfs ea overhead
+
+       # XATTR_SIZE_MAX less ldiskfs ea overhead
+       large_xattr_enabled && xattr_size_max=$((65536 - 84))
+       (( max_easize >= xattr_size_max )) ||
+               error "max_easize $max_easize < $xattr_size_max bytes"
+
+       test_mkdir $DIR/$tdir
+       $LFS setstripe -i $rand_ost $DIR/$tdir/$tfile ||
+               error "error creating $tfile on ost$rand_ost"
+       $LFS getstripe $DIR/$tdir/$tfile
+
+       local cmd
+       local idx
+       local found
+       local uuid
+
+       cmd="getstripe -i $DIR/$tdir/$tfile"
+       echo lfs $cmd
+       found=$($LFS $cmd)
+       (( $found == $rand_ost )) || error "index $found is not $rand_ost"
+
+       cmd="find $DIR/$tdir -i $rand_ost"
+       echo lfs $cmd
+       $LFS $cmd
+       found=$($LFS $cmd)
+       [[ "$found" == "$DIR/$tdir/$tfile" ]] ||
+               error "'lfs find' returned '$found', not '$tfile' by index"
 
-       restore_ostindex
+       $LFS osts
+       uuid=$(ostuuid_from_index $rand_ost)
+
+       cmd="find $DIR/$tdir -O $uuid"
+       echo lfs $cmd
+       $LFS $cmd
+       found=$($LFS $cmd)
+
+       [[ "$found" == "$DIR/$tdir/$tfile" ]] ||
+               error "'lfs find' returned '$found', not '$tfile' by UUID"
 }
 run_test 81 "sparse OST indexing"
 
@@ -6583,7 +6614,7 @@ test_82a() { # LU-4665
        mkdir $DIR/$tdir || error "mkdir $DIR/$tdir failed"
 
        stack_trap "do_nodes $(comma_list $(mdts_nodes)) \
-                  $LCTL get_param osp.*.prealloc_*_id" EXIT
+                  $LCTL get_param osp.*.prealloc_*_id || true" EXIT
 
        # 1. If the file does not exist, new file will be created
        #    with specified OSTs.
@@ -6642,20 +6673,9 @@ test_82a() { # LU-4665
        else
                echo "need MDS+client version at least 2.11.53"
        fi
-
-       restore_ostindex
 }
 run_test 82a "specify OSTs for file (succeed) or directory (succeed)"
 
-cleanup_82b() {
-       trap 0
-
-       # Remove OSTs from a pool and destroy the pool.
-       destroy_pool $ost_pool || true
-
-       restore_ostindex
-}
-
 # Test 82b is run to ensure that if the user supplies a pool with a specific
 # stripe layout that it behaves proprerly. It should fail in the case that
 # the supplied OST index list points to OSTs not contained in the user
@@ -6680,7 +6700,7 @@ test_82b() { # LU-4665
        done
        ost_indices=$(comma_list $ost_indices)
 
-       trap "restore_ostindex" EXIT
+       stack_trap "restore_ostindex" EXIT
        echo -e "\nFormat $OSTCOUNT OSTs with sparse indices $ost_indices"
        OST_INDEX_LIST=[$ost_indices] formatall
 
@@ -6702,9 +6722,6 @@ test_82b() { # LU-4665
        local ost_pool=$FSNAME.$TESTNAME
        create_pool $ost_pool || error "create OST pool $ost_pool failed"
 
-       trap - EXIT
-       trap "cleanup_82b" EXIT
-
        local ost_idx_in_list=${ost_indices##*,}
        local ost_idx_in_pool=$(exclude_items_from_list $ost_indices \
                                $ost_idx_in_list)
@@ -6747,8 +6764,6 @@ test_82b() { # LU-4665
        check_obdidx $file $ost_idx_in_list
        dd if=/dev/urandom of=$file count=1 bs=1M > /dev/null 2>&1 ||
                error "write $file failed"
-
-       cleanup_82b
 }
 run_test 82b "specify OSTs for file with --pool and --ost-list options"
 
index 58597de..7a3666b 100644 (file)
@@ -2217,11 +2217,11 @@ enum tgt_type {
  * there are more OSTs than allocated to uuidp, then an error is returned with
  * the ost_count set to number of available obd uuids.
  */
-static int llapi_get_target_uuids(int fd, struct obd_uuid *uuidp,
+static int llapi_get_target_uuids(int fd, struct obd_uuid *uuidp, int *indices,
                                  int *ost_count, enum tgt_type type)
 {
        char buf[PATH_MAX], format[32];
-       int rc = 0, index = 0;
+       int i, rc = 0;
        struct obd_uuid name;
        glob_t param;
        FILE *fp;
@@ -2250,20 +2250,25 @@ static int llapi_get_target_uuids(int fd, struct obd_uuid *uuidp,
 
        snprintf(format, sizeof(format),
                 "%%d: %%%zus", sizeof(uuidp[0].uuid) - 1);
-       while (fgets(buf, sizeof(buf), fp) != NULL) {
-               if (uuidp && (index < *ost_count)) {
-                       if (sscanf(buf, format, &index, uuidp[index].uuid) < 2)
-                               break;
+       for (i = 0; fgets(buf, sizeof(buf), fp); i++) {
+               int index;
+
+               if (sscanf(buf, format, &index, name.uuid) < 2)
+                       break;
+
+               if (i < *ost_count) {
+                       if (uuidp != NULL)
+                               uuidp[i] = name;
+                       if (indices != NULL)
+                               indices[i] = index;
                }
-               index++;
        }
-
        fclose(fp);
 
-       if (uuidp && (index > *ost_count))
+       if (uuidp && (i > *ost_count))
                rc = -EOVERFLOW;
 
-       *ost_count = index;
+       *ost_count = i;
 free_param:
        cfs_free_param_data(&param);
        return rc;
@@ -2271,7 +2276,7 @@ free_param:
 
 int llapi_lov_get_uuids(int fd, struct obd_uuid *uuidp, int *ost_count)
 {
-       return llapi_get_target_uuids(fd, uuidp, ost_count, LOV_TYPE);
+       return llapi_get_target_uuids(fd, uuidp, NULL, ost_count, LOV_TYPE);
 }
 
 int llapi_get_obd_count(char *mnt, int *count, int is_mdt)
@@ -2418,9 +2423,10 @@ static int setup_indexes(int d, char *path, struct obd_uuid *obduuids,
                         int num_obds, int **obdindexes, int *obdindex,
                         enum tgt_type type)
 {
-       int ret, obdcount, obd_valid = 0, obdnum;
+       int ret, obdcount, maxidx, obd_valid = 0, obdnum;
        long i;
        struct obd_uuid *uuids = NULL;
+       int *indices = NULL;
        char buf[16];
        int *indexes;
 
@@ -2435,17 +2441,26 @@ static int setup_indexes(int d, char *path, struct obd_uuid *obduuids,
        uuids = malloc(obdcount * sizeof(struct obd_uuid));
        if (uuids == NULL)
                return -ENOMEM;
+       indices = malloc(obdcount * sizeof(int));
+       if (indices == NULL) {
+               free(uuids);
+               return -ENOMEM;
+       }
+       maxidx = obdcount;
 
 retry_get_uuids:
-       ret = llapi_get_target_uuids(d, uuids, &obdcount, type);
+       ret = llapi_get_target_uuids(d, uuids, indices, &obdcount, type);
        if (ret) {
                if (ret == -EOVERFLOW) {
                        struct obd_uuid *uuids_temp;
+                       int *indices_temp;
 
                        uuids_temp = realloc(uuids, obdcount *
                                             sizeof(struct obd_uuid));
-                       if (uuids_temp != NULL) {
+                       indices_temp = realloc(indices, obdcount * sizeof(int));
+                       if (uuids_temp != NULL && indices_temp != NULL) {
                                uuids = uuids_temp;
+                               indices = indices_temp;
                                goto retry_get_uuids;
                        }
                        ret = -ENOMEM;
@@ -2466,20 +2481,21 @@ retry_get_uuids:
 
                /* The user may have specified a simple index */
                i = strtol(obduuids[obdnum].uuid, &end, 0);
-               if (end && *end == '\0' && i < obdcount) {
+               if (end && *end == '\0' && i < maxidx) {
                        indexes[obdnum] = i;
                        obd_valid++;
                } else {
                        for (i = 0; i < obdcount; i++) {
                                if (llapi_uuid_match(uuids[i].uuid,
                                                     obduuids[obdnum].uuid)) {
-                                       indexes[obdnum] = i;
+                                       indexes[obdnum] = indices[i];
                                        obd_valid++;
                                        break;
                                }
                        }
                }
-               if (i >= obdcount) {
+
+               if (i >= maxidx) {
                        indexes[obdnum] = OBD_NOT_FOUND;
                        llapi_err_noerrno(LLAPI_MSG_ERROR,
                                          "invalid obduuid '%s'",
@@ -2497,6 +2513,8 @@ retry_get_uuids:
 out_free:
        if (uuids)
                free(uuids);
+       if (indices)
+               free(indices);
 
        return ret;
 }