From: John L. Hammond Date: Mon, 21 Feb 2022 20:53:42 +0000 (-0600) Subject: EX-4539 lipe: add -perm to lipe_find3 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=ffe1138aad7adf030039477e7182edaa921782df;p=fs%2Flustre-release.git EX-4539 lipe: add -perm to lipe_find3 Fill in the -perm test in lipe_find3. Populate sanity-lipe-find3 test_101() to verify. Test-Parameters: trivial testlist=sanity-lipe-find3 Signed-off-by: John L. Hammond Change-Id: Ib201503247101619416c39ae97f5068230441863 Reviewed-on: https://review.whamcloud.com/46576 Tested-by: jenkins Tested-by: Maloo --- diff --git a/lipe/src/lipe_find3/lf3_debug.h b/lipe/src/lipe_find3/lf3_debug.h index 1c5ff2c..8884d94 100644 --- a/lipe/src/lipe_find3/lf3_debug.h +++ b/lipe/src/lipe_find3/lf3_debug.h @@ -21,7 +21,9 @@ static inline const char *lf3_progname(void) } while (0) #define LF3_DEBUG_B(x) LF3_DEBUG("%s = %s\n", #x, (x) ? "true" : "false") +#define LF3_DEBUG_C(x) LF3_DEBUG("%s = %c\n", #x, (x)) #define LF3_DEBUG_D(x) LF3_DEBUG("%s = %"PRIdMAX"\n", #x, (intmax_t)(x)) +#define LF3_DEBUG_O(x) LF3_DEBUG("%s = %"PRIoMAX"\n", #x, (intmax_t)(x)) #define LF3_DEBUG_P(x) LF3_DEBUG("%s = %p\n", #x, x) #define LF3_DEBUG_S(x) LF3_DEBUG("%s = '%s'\n", #x, x) #define LF3_DEBUG_U(x) LF3_DEBUG("%s = %"PRIuMAX"\n", #x, (uintmax_t)(x)) diff --git a/lipe/src/lipe_find3/lf3_parse.y b/lipe/src/lipe_find3/lf3_parse.y index ab3c77f..448eec7 100644 --- a/lipe/src/lipe_find3/lf3_parse.y +++ b/lipe/src/lipe_find3/lf3_parse.y @@ -423,6 +423,166 @@ static char *lf3_numeric_expr(const char *thunk, int begin, int end) return xsprintf("(%c (%s) %llu)", cmp, thunk, val); } +static int lf3_parse_perm1(const char *t, mode_t *mode) +{ + /* Parse [ugoa]+[+=-][rwx]+ */ + mode_t ugo = 0, rwx = 0; + int opc = '\0'; + + LF3_DEBUG_S(t); + + /* TODO Xst */ + + for (; *t != '\0' && opc == '\0'; t++) { + switch (*t) { + case 'u': + ugo |= S_IRWXU; + break; + case 'g': + ugo |= S_IRWXG; + break; + case 'o': + ugo |= S_IRWXO; + break; + case 'a': + ugo |= S_IRWXU | S_IRWXG | S_IRWXO; + break; + case '+': + case '-': + case '=': + opc = *t; + break; + default: + return -EINVAL; + } + } + + if (ugo == 0 || opc == '\0') + return -EINVAL; + + LF3_DEBUG_S(t); + + for (; *t != '\0'; t++) { + switch (*t) { + case 'r': + rwx |= S_IRUSR | S_IRGRP | S_IROTH; + break; + case 'w': + rwx |= S_IWUSR | S_IWGRP | S_IWOTH; + break; + case 'x': + rwx |= S_IXUSR | S_IXGRP | S_IXOTH; + break; + default: + return -EINVAL; + } + } + + LF3_DEBUG_O(ugo); + LF3_DEBUG_O(rwx); + LF3_DEBUG_C(opc); + + switch (opc) { + case '+': + *mode |= (ugo & rwx); + break; + case '-': + *mode &= ~(ugo & rwx); + break; + case '=': + *mode &= ~ugo; + *mode |= (ugo & rwx); + break; + } + + LF3_DEBUG_O(*mode); + + return 0; +} + +static int lf3_parse_perm(const char *str, mode_t *mode) +{ + /* Parse "0644" or "([ugoa][+=][rwx]+),(...),..." */ + + char *end = NULL; + char *str1 = NULL, *s, *t; + int rc; + + if (isdigit(*str)) { + errno = 0; + *mode = strtoul(str, &end, 8); + rc = (errno == 0 && *end == '\0') ? 0 : -EINVAL; + goto out; + } + + *mode = 0; + + s = str1 = xstrdup(str); + + while ((t = strsep(&s, ",")) != NULL) { + rc = lf3_parse_perm1(t, mode); + if (rc < 0) + goto out; + } + + rc = 0; +out: + free(str1); + + return rc; +} + +static char *lf3_perm_expr(int begin, int end) +{ + const char *mode_str = lf3_arg[begin + 1]; + mode_t mode = 0; + enum { + PERM_MATCH_EQ, + PERM_MATCH_ALL, + PERM_MATCH_ANY, + } match; + int rc; + + assert(begin + 2 == end); + + /* -perm mode : File's permission bits are exactly mode (octal or symbolic) + * -perm -mode : All of the permission bits mode are set for the file + * -perm /mode : Any of the permission bits mode are set for the file */ + + switch (mode_str[0]) { + default: + match = PERM_MATCH_EQ; + break; + case '-': + match = PERM_MATCH_ALL; + mode_str++; + break; + case '/': + match = PERM_MATCH_ANY; + mode_str++; + break; + } + + enum { + PERM_MASK = S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO, + }; + + rc = lf3_parse_perm(mode_str, &mode); + if (rc < 0) + LF3_FATAL_AT(begin + 1, "invalid mode '%s'\n", lf3_arg[begin + 1]); + + switch (match) { + case PERM_MATCH_EQ: + return xsprintf("(= (logand (mode) %llu) %llu)", (__ull)PERM_MASK, (__ull)mode); + case PERM_MATCH_ALL: + return xsprintf("(= (logand (mode) %llu) %llu)", (__ull)mode, (__ull)mode); + case PERM_MATCH_ANY: + return xsprintf("(not (= (logand (mode) %llu) 0))", (__ull)mode); + default: + abort(); /* I <3 GCC! */ + } +} + static char *lf3_type_expr(int begin, int end) { const char *type_str = lf3_arg[begin + 1]; @@ -911,7 +1071,7 @@ static char *lf3_simple_expr(int begin, int end) X1(size); X1(type); X1(exec); - // X1(perm); TODO + X1(perm); // X1(used); TODO X1(print); X1(print0); diff --git a/lustre/tests/sanity-lipe-find3.sh b/lustre/tests/sanity-lipe-find3.sh index f1206b7..ec5f818 100644 --- a/lustre/tests/sanity-lipe-find3.sh +++ b/lustre/tests/sanity-lipe-find3.sh @@ -256,8 +256,72 @@ declare -r S_IFREG=0100000 declare -a MODES=(0 1 0111 0222 0444 0555 0666 0777) test_101() { - # TODO - true + local facet=mds1 + local device="$(facet_device $facet)" + local file=$MOUNT/$tfile + local fid + + init_lipe_find3_env "$file" + fid=$($LFS path2fid "$file") + chmod 0666 "$file" + + expect1 "$fid" lipe_find3_facet mds1 -perm 0666 + expect1 "$fid" lipe_find3_facet mds1 -perm -0666 + expect1 "$fid" lipe_find3_facet mds1 -perm -0600 + expect1 "$fid" lipe_find3_facet mds1 -perm -0060 + expect1 "$fid" lipe_find3_facet mds1 -perm -0400 + expect1 "$fid" lipe_find3_facet mds1 -perm /0777 + expect1 "$fid" lipe_find3_facet mds1 -perm /0477 + + expect_empty lipe_find3_facet mds1 -perm 0777 + expect_empty lipe_find3_facet mds1 -perm 0667 + expect_empty lipe_find3_facet mds1 -perm 0700 + expect_empty lipe_find3_facet mds1 -perm /0100 + expect_empty lipe_find3_facet mds1 -perm /0111 + + expect1 "$fid" lipe_find3_facet mds1 -perm ugo=rw + expect1 "$fid" lipe_find3_facet mds1 -perm -ugo=rw + expect1 "$fid" lipe_find3_facet mds1 -perm -ug=rw + expect1 "$fid" lipe_find3_facet mds1 -perm -u=rw + expect1 "$fid" lipe_find3_facet mds1 -perm -ugo=r + expect1 "$fid" lipe_find3_facet mds1 -perm -ugo=w + + expect_empty lipe_find3_facet mds1 -perm ugo=rwx + expect_empty lipe_find3_facet mds1 -perm ug=wx,o=rwx + expect_empty lipe_find3_facet mds1 -perm u=rwx + expect_empty lipe_find3_facet mds1 -perm u=x + expect_empty lipe_find3_facet mds1 -perm ugo=rwx + + chmod 0001 "$file" + expect1 "$fid" lipe_find3_facet mds1 -perm 0001 + expect1 "$fid" lipe_find3_facet mds1 -perm o=x + expect1 "$fid" lipe_find3_facet mds1 -perm -o=x + expect1 "$fid" lipe_find3_facet mds1 -perm /a=x + expect_empty lipe_find3_facet mds1 -perm 0 + expect_empty lipe_find3_facet mds1 -perm 0000 + expect_empty lipe_find3_facet mds1 -perm u=x + expect_empty lipe_find3_facet mds1 -perm -u=x + expect_empty lipe_find3_facet mds1 -perm /u=x + expect_empty lipe_find3_facet mds1 -perm ugo= + + chmod 0000 "$file" + expect1 "$fid" lipe_find3_facet mds1 -perm 0000 + expect1 "$fid" lipe_find3_facet mds1 -perm ugo= + expect_empty lipe_find3_facet mds1 -perm -o=x + expect_empty lipe_find3_facet mds1 -perm /a=x + + # ... + expect_error lipe_find3_facet mds1 -perm 0q + expect_error lipe_find3_facet mds1 -perm 9 + expect_error lipe_find3_facet mds1 -perm k=rxw + expect_error lipe_find3_facet mds1 -perm u@rwx + expect_error lipe_find3_facet mds1 -perm u=rwq + expect_error lipe_find3_facet mds1 -perm u=q + expect_error lipe_find3_facet mds1 -perm ugk=r + expect_error lipe_find3_facet mds1 -perm = + expect_error lipe_find3_facet mds1 -perm =r + expect_error lipe_find3_facet mds1 -perm '' + expect_error lipe_find3_facet mds1 -perm } run_test 101 "lipe_find3 perm does the right thing"