Whamcloud - gitweb
EX-4539 lipe: add -perm to lipe_find3
authorJohn L. Hammond <jhammond@whamcloud.com>
Mon, 21 Feb 2022 20:53:42 +0000 (14:53 -0600)
committerJohn L. Hammond <jhammond@whamcloud.com>
Thu, 10 Mar 2022 17:26:07 +0000 (17:26 +0000)
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 <jhammond@whamcloud.com>
Change-Id: Ib201503247101619416c39ae97f5068230441863
Reviewed-on: https://review.whamcloud.com/46576
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
lipe/src/lipe_find3/lf3_debug.h
lipe/src/lipe_find3/lf3_parse.y
lustre/tests/sanity-lipe-find3.sh

index 1c5ff2c..8884d94 100644 (file)
@@ -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))
index ab3c77f..448eec7 100644 (file)
@@ -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);
index f1206b7..ec5f818 100644 (file)
@@ -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"