Whamcloud - gitweb
LU-16946 utils: allow lfs find time within a range 71/55271/6
authorFrederick Dilger <fdilger@whamcloud.com>
Thu, 30 May 2024 22:00:57 +0000 (18:00 -0400)
committerOleg Drokin <green@whamcloud.com>
Mon, 10 Jun 2024 06:14:39 +0000 (06:14 +0000)
If multiple times are specified on the command-line like:

        lfs find -atime +60 -atime -90 ...

use those times as the upper and lower bounds of the margin.
This makes it easier to find files that were created within
a specific range of dates.

While working on this patch I noticed that that margin
bounds are a little odd; using the range:

(limit - margin, limit]

instead of what I intuitively thought,

(limit - margin, limit + margin)

The logic behind this is unknown to me, but it can be found
'liblustreapi.c' in the method 'find_value_cmp()'.
However, for the time being, when using a time range, it will
simply shift the limit to the largest of the two and have
the margin cover the difference.

Signed-off-by: Frederick Dilger <fdilger@whamcloud.com>
Change-Id: I2e5b856396472eab91e1d2c3214f304010601a41
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/55271
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Jian Yu <yujian@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/doc/lfs-find.1
lustre/tests/sanity.sh
lustre/utils/lfs.c

index 52e38e6..9a9a6ba 100644 (file)
@@ -64,7 +64,13 @@ are specified, the margin of error is based on the smallest unit used, so
 .B -atime 3d
 has a margin of error of one day, while
 .B -atime 72h
-has a margin of error of one hour.
+has a margin of error of one hour.  If both
+.BI "-atime +" older
+and
+.BI "-atime -" newer
+are used, then files with atime within the range
+.IR older - newer
+are matched.
 .TP
 .BR --attrs
 File has ATTRS attribute flags. Supported attributes are (non exhaustive list):
index 76f2d0a..e4f1d67 100755 (executable)
@@ -7133,6 +7133,51 @@ test_56od() {
 }
 run_test 56od "check lfs find -btime with units"
 
+test_56oe() {
+       local dir=$DIR/$tdir
+       local expected=5
+       local unit=hour
+
+       # just to make sure there is something that won't be found
+       test_mkdir $dir
+       touch $dir/$tfile.now
+
+       for ((val = 1; val <= 10; val++)); do
+               touch $dir/$tfile-a.$val $dir/$tfile-m.$val
+               touch $dir/$tfile-c.$val
+               touch --date="$val $unit ago" -a $dir/$tfile-a.$val
+               touch --date="$val $unit ago" -m $dir/$tfile-m.$val
+               (( val % 5 != 2 )) || sleep 10
+       done
+
+       cmd="$LFS find $dir -ctime -19s -ctime +9s"
+       nums=$($cmd | grep -c c.*)
+
+       (( nums == expected )) ||
+               error "'$cmd' wrong: found $nums, expected $expected"
+
+       local cmd="$LFS find $dir -atime +7h30m -atime -2h30m"
+       local nums=$($cmd | wc -l)
+
+       (( $($cmd | grep -c a.7) == 1 )) ||
+               error "'$cmd' didn't capture file accessed 7 hours ago"
+       (( $($cmd | grep -c a.3) == 1 )) ||
+               error "'$cmd' didn't capture file accessed 3 hours ago"
+       (( nums == expected )) ||
+               error "'$cmd' wrong: found $nums, expected $expected"
+
+       cmd="$LFS find $dir -mtime -7h30m -mtime +2h30m"
+       nums=$($cmd | wc -l)
+
+       (( $($cmd | grep -c m.7) == 1 )) ||
+               error "'$cmd' didn't capture file modified 7 hours ago"
+       (( $($cmd | grep -c m.3) == 1 )) ||
+               error "'$cmd' didn't capture file modified 3 hours ago"
+       (( nums == expected )) ||
+               error "'$cmd' wrong: found $nums, expected $expected"
+}
+run_test 56oe "check lfs find with time range"
+
 test_56p() {
        [ $RUNAS_ID -eq $UID ] &&
                skip_env "RUNAS_ID = UID = $UID -- skipping"
index e2bf6ca..5cb6c33 100755 (executable)
@@ -4656,13 +4656,15 @@ static int lfs_poollist(int argc, char **argv)
 }
 
 #define FP_DEFAULT_TIME_MARGIN (24 * 60 * 60)
-static int set_time(struct find_param *param, time_t *time, time_t *set,
-                   char *str)
+static int set_time(struct find_param *param, time_t *time, time_t *set_t,
+                      int *sign_t, char *str)
 {
        long long t = 0;
        int sign = 0;
        char *endptr = "AD";
        char *timebuf;
+       time_t prev_set = 0;
+       int prev_sign = 0;
 
        if (str[0] == '+')
                sign = 1;
@@ -4672,6 +4674,11 @@ static int set_time(struct find_param *param, time_t *time, time_t *set,
        if (sign)
                str++;
 
+       if (*set_t) {
+               prev_set = *set_t;
+               prev_sign = *sign_t;
+       }
+
        for (timebuf = str; *endptr && *(endptr + 1); timebuf = endptr + 1) {
                long long val = strtoll(timebuf, &endptr, 0);
                int unit = 1;
@@ -4721,7 +4728,17 @@ static int set_time(struct find_param *param, time_t *time, time_t *set,
                return INT_MAX;
        }
 
-       *set = *time - t;
+       *set_t = *time - t;
+       /* if user requested a time range via "-xtime +M -xtime -N" then
+        * use the largest time and increase margin to cover the difference
+        * This will occur as long as the signs differ.
+        */
+       if (sign * prev_sign == -1) {
+               param->fp_time_margin = abs(*set_t - prev_set);
+               if (prev_set > *set_t)
+                       *set_t = prev_set;
+               return 0;
+       }
 
        return sign;
 }
@@ -5530,13 +5547,12 @@ static int lfs_find(int argc, char **argv)
                                xsign = &param.fp_msign;
                                param.fp_exclude_mtime = !!neg_opt;
                        }
-                       rc = set_time(&param, &t, xtime, optarg);
+                       rc = set_time(&param, &t, xtime, xsign, optarg);
                        if (rc == INT_MAX) {
                                ret = -1;
                                goto err;
                        }
-                       if (rc)
-                               *xsign = rc;
+                       *xsign = rc;
                        break;
                case LFS_ATTRS_OPT:
                        ret = name2attrs(optarg, &param.fp_attrs,