Whamcloud - gitweb
LU-16167 obdclass: fix lctl llog_print with skipped records 86/48586/8
authorEtienne AUJAMES <etienne.aujames@cea.fr>
Mon, 19 Sep 2022 10:23:47 +0000 (12:23 +0200)
committerOleg Drokin <green@whamcloud.com>
Mon, 14 Nov 2022 08:25:12 +0000 (08:25 +0000)
The 2a5b50d ignores the skipped records in configuration llog.
But if ioctl OBD_IOC_LLOG_PRINT return 0 record to display,
jt_llog_print_iter() will stop the processing and ignore the
non-skipped records at the end of the llog.

This patch returns to user space if the last index processed
(by llog_print_cb) is the last of llog file. If true,
jt_llog_print_iter() stops the processing.

Add regression test "conf-sanity test_123ai" for this issue.

Fixes: 2a5b50d ("LU-15142 lctl: fixes for set_param -P and llog_print")
Test-Parameters: testlist=conf-sanity env=ONLY=123ai,SLOW=yes,ONLY_REPEAT=10
Signed-off-by: Etienne AUJAMES <etienne.aujames@cea.fr>
Change-Id: I78395268c57555e4fd2a4048ccf5b6132ca2877f
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/48586
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Alexander <alexander.boyko@hpe.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/obdclass/llog_ioctl.c
lustre/tests/conf-sanity.sh
lustre/utils/obd.c

index 6a3a41e..b215ac6 100644 (file)
@@ -198,6 +198,19 @@ static int llog_check_cb(const struct lu_env *env, struct llog_handle *handle,
        RETURN(rc);
 }
 
+static inline bool llog_idx_is_eof(struct llog_handle *llh, __u32 cur_idx)
+{
+       __u32 last_idx = llh->lgh_last_idx;
+
+       /* catalog is wrapped ? */
+       if (unlikely(llh->lgh_hdr->llh_flags & LLOG_F_IS_CAT &&
+                    llh->lgh_hdr->llh_cat_idx >= llh->lgh_last_idx &&
+                    llh->lgh_hdr->llh_count > 1))
+               last_idx = LLOG_HDR_BITMAP_SIZE(llh->lgh_hdr) - 1;
+
+       return cur_idx >= last_idx;
+}
+
 struct llog_print_data {
        struct obd_ioctl_data *lprd_data;
        unsigned int           lprd_cfg_flags;
@@ -217,7 +230,10 @@ static int llog_print_cb(const struct lu_env *env, struct llog_handle *handle,
        int rc;
 
        ENTRY;
-       if (ioc_data && ioc_data->ioc_inllen1 > 0) {
+       if (unlikely(!ioc_data))
+               RETURN(-EINVAL);
+
+       if (ioc_data->ioc_inllen1 > 0) {
                l = 0;
                remains = ioc_data->ioc_inllen4 +
                          round_up(ioc_data->ioc_inllen1, 8) +
@@ -237,6 +253,7 @@ static int llog_print_cb(const struct lu_env *env, struct llog_handle *handle,
        }
 
        cur_index = rec->lrh_index;
+       ioc_data->ioc_u32_2 = llog_idx_is_eof(handle, cur_index);
        if (from > MARKER_DIFF && cur_index >= from - MARKER_DIFF &&
            cur_index < from) {
                /* LU-15706: try to remember the marker cfg_flag that the "from"
index b05cbc6..c026a10 100644 (file)
@@ -9692,6 +9692,55 @@ test_123ah() { #LU-7668 del_ost
 }
 run_test 123ah "del_ost cancels config log entries correctly"
 
+cleanup_123ai() {
+       local timeout=$1
+
+       echo "cleanup test 123ai"
+
+       # cancel last timeout record
+       do_facet mgs "$LCTL set_param -P -d timeout"
+
+       # restore timeout value
+       do_nodes $(comma_list $(all_nodes)) "$LCTL set_param timeout=$timeout"
+}
+
+test_123ai() { #LU-16167
+       local i
+       local count
+       local old_count
+       local old_timeout
+
+       remote_mgs_nodsh && skip "remote MGS with nodsh"
+       (( MDS1_VERSION >= $(version_code 2.15.51) )) ||
+               skip "Need MDS version at least 2.15.51"
+
+       [ -d $MOUNT/.lustre ] || setup
+
+       old_count=$(do_facet mgs "$LCTL --device MGS llog_print -r params" |
+               grep -c "parameter: timeout")
+
+       old_timeout=$($LCTL get_param -n timeout)
+       stack_trap "cleanup_123ai $old_timeout" EXIT
+
+       # add and cancel params (2 * MAX_IOC_BUFLEN / 128 + 1 = 129)
+       for i in {1..129}; do
+               do_facet mgs "$LCTL set_param -P timeout=$i" ||
+                       error "fail to set timeout=$i on MGS"
+       done
+
+       count=$(do_facet mgs "$LCTL --device MGS llog_print -r params" |
+               grep -c "parameter: timeout")
+
+       ((count - old_count == 129)) ||
+               error "number timeout record missmatch ($count - $old_count != 129)"
+
+       do_facet mgs "$LCTL --device MGS llog_print params" |
+               tail -1 | grep  "timeout, value: 129" ||
+               error "llog_print could not display the last record (timeout=129)"
+
+}
+run_test 123ai "llog_print display all non skipped records"
+
 test_123F() {
        remote_mgs_nodsh && skip "remote MGS with nodsh"
 
index ebb1fcb..e229646 100644 (file)
@@ -2696,8 +2696,9 @@ int jt_llog_print_iter(char *logname, long start, long end,
        long rec;
        int rc = 0;
 
+       /* default end of indexes is max indexes in a llog bitmap */
        if (end == -1)
-               end = 0x7fffffff;
+               end = LLOG_MIN_CHUNK_SIZE * 8 - 1;
 
        data.ioc_dev = cur_device;
        data.ioc_inlbuf1 = logname;
@@ -2714,6 +2715,7 @@ int jt_llog_print_iter(char *logname, long start, long end,
         */
        for (rec = start; rec < end; rec += inc) {
                char *record = ((struct obd_ioctl_data *)buf)->ioc_bulk;
+               __u32 *is_llog_eof = &((struct obd_ioctl_data *)buf)->ioc_u32_2;
 
 retry:
                snprintf(startbuf, sizeof(startbuf), "%lu", rec);
@@ -2751,13 +2753,16 @@ retry:
                        goto out;
                }
 
-               /* There is no "end of list" marker, record was not modified */
-               if (strcmp(record, logname) == 0)
-                       break;
-
-               rc = llog_process_records(record_cb, record, private, reverse);
+               /* record was not modified -> all indexes are skipped */
+               if (strcmp(record, logname) != 0)
+                       rc = llog_process_records(record_cb, record, private,
+                                                 reverse);
                if (rc)
                        goto out;
+
+               /* end of llog file ? */
+               if (*is_llog_eof)
+                       break;
        }
 
 out: