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>
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;
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) +
}
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"
}
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"
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;
*/
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);
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: