From 70d8107c48abe2f82f714ca82e488d953642ce06 Mon Sep 17 00:00:00 2001 From: Lei Feng Date: Tue, 30 Jul 2024 12:14:18 +0800 Subject: [PATCH] LU-16622 utils: 'lfs find --ost' supports index range 'lfs find --ost' command can accept an index range. For example lfs find --ost 0,1-3 It equals to: lfs find --ost 0,1,2,3 'lfs find --mdt' can accept index range too. Signed-off-by: Lei Feng Test-Parameters: trivial Change-Id: I094aa480c97440dad8ffaac8af902682b5916d6c Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/55902 Reviewed-by: Andreas Dilger Reviewed-by: Emoly Liu Reviewed-by: Oleg Drokin Tested-by: jenkins Tested-by: Maloo --- lustre/doc/lfs-find.1 | 6 +-- lustre/tests/sanity.sh | 27 ++++++++++ lustre/utils/lfs.c | 142 ++++++++++++++++++++++++++++--------------------- 3 files changed, 110 insertions(+), 65 deletions(-) diff --git a/lustre/doc/lfs-find.1 b/lustre/doc/lfs-find.1 index 7d1d6ee..352790f 100644 --- a/lustre/doc/lfs-find.1 +++ b/lustre/doc/lfs-find.1 @@ -81,7 +81,7 @@ lfs-find \- Lustre client utility to list files with specific attributes .br .RB [[ ! ] .BR --mdt | --mdt-index | -m -.IR UUID | INDEX ", ...]" +.IR UUID | INDEX | INDEX_RANGE ", ...]" .br .RB [[ ! ] .BR --mdt-count | -T @@ -113,7 +113,7 @@ lfs-find \- Lustre client utility to list files with specific attributes .IR REFERENCE ] .RB [[ ! ] .BR --ost | -O -.IR INDEX ", ...]" +.IR INDEX | INDEX_RANGE ", ...]" .br .RB [[ ! ] .B --perm @@ -469,7 +469,7 @@ this test will fail for any files where the birth time is unknown. .BR -O ", " --ost File has an object on the specified OST(s). The OST names can be specified using the whole OST target name, -or just the OST index number. +or just the OST index number, or OST index range like 0-3. If multiple OSTs are given in a comma-separated list, the file may have an object on any of the given OSTs. Specifying multiple OSTs allows scanning the filesystem only once diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index d3cda5d..945a0fb 100755 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -7124,6 +7124,33 @@ test_56i() { } run_test 56i "check 'lfs find -ost UUID' skips directories" +test_56ib() { + local dir=$DIR/$tdir + local file=$dir/$tfile + local idx=$((RANDOM % $OSTCOUNT)) + local find_file + local cmd + + test_mkdir $dir + echo "create file $file on OST $idx" + $LFS setstripe $file -o $idx|| + error "failed to create test file $file" + + cmd="$LFS find --ost 0,1-$idx,$idx $dir" + echo "Command: $cmd" + find_file=$($cmd) + echo "lfs find result: $find_file" + [[ "$find_file" == "$file" ]] || + error "file $file is NOT found" + + cmd="$LFS find ! --ost $idx-$((OSTCOUNT-1)),$idx $dir" + echo "Command: $cmd" + find_file=$($cmd) + [[ -z "$find_file" ]] || + error "should NOT find any file, but find $find_file" +} +run_test 56ib "check 'lfs find -ost INDEX_RANGE' command" + test_56j() { local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE diff --git a/lustre/utils/lfs.c b/lustre/utils/lfs.c index bbb4284..fb9b9c1 100755 --- a/lustre/utils/lfs.c +++ b/lustre/utils/lfs.c @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -6160,79 +6161,96 @@ static int lfs_find(int argc, char **argv) case 'm': case 'i': case 'O': { - char *buf, *token, *next, *p; - int len = 1; - void *tmp; - - buf = strdup(optarg); - if (!buf) { - ret = -ENOMEM; - goto err; - } + int len, rc2; + int *p_num, *p_alloc; + struct obd_uuid **pp_uuid, *tmp; + const char *p1 = optarg, *p2; + char buf[UUID_MAX]; + const char *pattern = "^([0-9]+)-([0-9]+)$"; + regex_t reg; + regmatch_t pmatch[3]; param.fp_exclude_obd = !!neg_opt; - - token = buf; - while (token && *token) { - token = strchr(token, ','); - if (token) { - len++; - token++; - } - } if (c == 'm') { - param.fp_exclude_mdt = !!neg_opt; - param.fp_num_alloc_mdts += len; - tmp = realloc(param.fp_mdt_uuid, - param.fp_num_alloc_mdts * - sizeof(*param.fp_mdt_uuid)); - if (!tmp) { - ret = -ENOMEM; - goto err_free; - } - - param.fp_mdt_uuid = tmp; + p_num = ¶m.fp_num_mdts; + p_alloc = ¶m.fp_num_alloc_mdts; + pp_uuid = ¶m.fp_mdt_uuid; } else { - param.fp_exclude_obd = !!neg_opt; - param.fp_num_alloc_obds += len; - tmp = realloc(param.fp_obd_uuid, - param.fp_num_alloc_obds * - sizeof(*param.fp_obd_uuid)); - if (!tmp) { - ret = -ENOMEM; - goto err_free; - } - - param.fp_obd_uuid = tmp; + p_num = ¶m.fp_num_obds; + p_alloc = ¶m.fp_num_alloc_obds; + pp_uuid = ¶m.fp_obd_uuid; } - for (token = buf; token && *token; token = next) { - struct obd_uuid *puuid; + regcomp(®, pattern, REG_EXTENDED); - if (c == 'm') { - puuid = - ¶m.fp_mdt_uuid[param.fp_num_mdts++]; - } else { - puuid = - ¶m.fp_obd_uuid[param.fp_num_obds++]; - } - p = strchr(token, ','); - next = 0; - if (p) { - *p = 0; - next = p+1; - } + while (p1 && *p1 != '\0') { + /* grab one uuid/idx/idx_range */ + p2 = strchr(p1, ','); + if (p2 == NULL) + p2 = p1 + strlen(p1); - if (strlen(token) > sizeof(puuid->uuid) - 1) { + len = p2 - p1; + if (len >= sizeof(buf)) { + regfree(®); ret = -E2BIG; - goto err_free; + goto err; + } + strncpy(buf, p1, len); + buf[len] = '\0'; + + if (*p2 == '\0') + p1 = p2; + else + p1 = p2 + 1; + + /* extend array if necessary */ + if (*p_num >= *p_alloc) { + tmp = realloc(*pp_uuid, + (*p_alloc + 16) * + sizeof((*pp_uuid)[0])); + if (tmp == NULL) { + regfree(®); + ret = -ENOMEM; + goto err; + } + *pp_uuid = tmp; + *p_alloc += 16; } - strncpy(puuid->uuid, token, - sizeof(puuid->uuid)); + /* check pattern */ + rc2 = regexec(®, buf, 3, pmatch, 0); + if (rc2 == 0) { + /* idx range such as 0-3 */ + int start, end; + + start = atoi(&buf[pmatch[1].rm_so]); + end = atoi(&buf[pmatch[2].rm_so]); + for ( ; start <= end; start++) { + if (*p_num >= *p_alloc) { + tmp = realloc(*pp_uuid, + (*p_alloc + 16) * + sizeof((*pp_uuid)[0])); + if (tmp == NULL) { + regfree(®); + ret = -ENOMEM; + goto err; + } + *pp_uuid = tmp; + *p_alloc += 16; + } + sprintf(buf, "%d", start); + strcpy((*pp_uuid)[(*p_num)++].uuid, buf); + } + } else if (rc2 == REG_NOMATCH) { + /* single idx or uuid */ + strcpy((*pp_uuid)[(*p_num)++].uuid, buf); + } else { + regfree(®); + ret = -errno; + goto err; + } } -err_free: - if (buf) - free(buf); + + regfree(®); break; } #if LUSTRE_VERSION_CODE >= OBD_OCD_VERSION(2, 18, 53, 0) -- 1.8.3.1