From 1d97a8b4cd3de9074f323332c7b736367a70d419 Mon Sep 17 00:00:00 2001 From: Emoly Liu Date: Fri, 12 Jun 2020 16:12:00 +0800 Subject: [PATCH] LU-13609 llog: list all the log files correctly on MGS/MDT "lctl --device xxx llog_catlist" should list all the config log on MGS and catalog on MDT correctly without any buffer size limit. If data can't be fetched in one time, data->ioc_count is used to save the number of all the fetched logs and then continue. conf-sanity.sh test_123af is added to verify this patch. Signed-off-by: Emoly Liu Change-Id: I364d563446833751b1f017fa2bef0351dab56235 Reviewed-on: https://review.whamcloud.com/38917 Reviewed-by: Andreas Dilger Reviewed-by: Ben Evans Tested-by: jenkins Tested-by: Maloo Reviewed-by: Oleg Drokin --- lustre/include/obd_support.h | 1 + lustre/mgs/mgs_llog.c | 31 +++++++++++++++++++++++----- lustre/obdclass/llog_ioctl.c | 21 +++++++++++++++---- lustre/tests/conf-sanity.sh | 49 ++++++++++++++++++++++++++++++++++++++++++++ lustre/utils/obd.c | 41 +++++++++++++++++++++++------------- 5 files changed, 120 insertions(+), 23 deletions(-) diff --git a/lustre/include/obd_support.h b/lustre/include/obd_support.h index 492c2b9..52960d8 100644 --- a/lustre/include/obd_support.h +++ b/lustre/include/obd_support.h @@ -558,6 +558,7 @@ extern char obd_jobid_var[]; #define OBD_FAIL_LLOG_PURGE_DELAY 0x1318 #define OBD_FAIL_PLAIN_RECORDS 0x1319 #define OBD_FAIL_CATALOG_FULL_CHECK 0x131a +#define OBD_FAIL_CATLIST 0x131b #define OBD_FAIL_LLITE 0x1400 #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE 0x1401 diff --git a/lustre/mgs/mgs_llog.c b/lustre/mgs/mgs_llog.c index a8f8325..3025dfb 100644 --- a/lustre/mgs/mgs_llog.c +++ b/lustre/mgs/mgs_llog.c @@ -4478,8 +4478,9 @@ int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs, { struct list_head log_list; struct mgs_direntry *dirent, *n; - char *out, *suffix; - int l, remains, rc; + char *out, *suffix, prefix[] = "config_log: "; + int prefix_len = strlen(prefix); + int l, remains, start = 0, rc; ENTRY; @@ -4490,19 +4491,39 @@ int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs, out = data->ioc_bulk; remains = data->ioc_inllen1; + /* OBD_FAIL: fetch the config_log records from the specified one */ + if (OBD_FAIL_CHECK(OBD_FAIL_CATLIST)) + data->ioc_count = cfs_fail_val; + list_for_each_entry_safe(dirent, n, &log_list, mde_list) { list_del_init(&dirent->mde_list); suffix = strrchr(dirent->mde_name, '-'); if (suffix != NULL) { - l = scnprintf(out, remains, "config_log: %s\n", + l = prefix_len + dirent->mde_len + 1; + if (remains - 1 < 0) { + /* No enough space for this record */ + mgs_direntry_free(dirent); + goto out; + } + start++; + if (start < data->ioc_count) { + mgs_direntry_free(dirent); + continue; + } + l = scnprintf(out, remains, "%s%s\n", prefix, dirent->mde_name); out += l; remains -= l; } mgs_direntry_free(dirent); - if (remains <= 0) - break; + if (remains == 0) + /* Full */ + goto out; } + /* Finished */ + start = 0; +out: + data->ioc_count = start; RETURN(rc); } diff --git a/lustre/obdclass/llog_ioctl.c b/lustre/obdclass/llog_ioctl.c index 3db9ef5..894e2ea 100644 --- a/lustre/obdclass/llog_ioctl.c +++ b/lustre/obdclass/llog_ioctl.c @@ -497,15 +497,28 @@ int llog_catalog_list(const struct lu_env *env, struct dt_device *d, out = data->ioc_bulk; remains = data->ioc_inllen1; - for (i = 0; i < count; i++) { + /* OBD_FAIL: fetch the catalog records from the specified one */ + if (OBD_FAIL_CHECK(OBD_FAIL_CATLIST)) + data->ioc_count = cfs_fail_val - 1; + for (i = data->ioc_count; i < count; i++) { id = &idarray[i].lci_logid; l = snprintf(out, remains, "catalog_log: "DFID":%x\n", - PFID(&id->lgl_oi.oi_fid), id->lgl_ogen); + PFID(&id->lgl_oi.oi_fid), id->lgl_ogen); out += l; remains -= l; - if (remains <= 0) - break; + if (remains <= 0) { + if (remains < 0) { + /* the print is not complete */ + remains += l; + data->ioc_bulk[out - data->ioc_bulk - l] = '\0'; + data->ioc_count = i; + } else { + data->ioc_count = i++; + } + goto out; + } } + data->ioc_count = 0; out: OBD_FREE_LARGE(idarray, size); RETURN(rc); diff --git a/lustre/tests/conf-sanity.sh b/lustre/tests/conf-sanity.sh index 7cea4cb..3c6a42a 100644 --- a/lustre/tests/conf-sanity.sh +++ b/lustre/tests/conf-sanity.sh @@ -8744,6 +8744,55 @@ test_123ae() { # LU-11566 } run_test 123ae "llog_cancel can cancel requested record" +test_123af() { #LU-13609 + [ "$MGS_VERSION" -ge $(version_code 2.13.54) -a \ + "$MDS1_VERSION" -ge $(version_code 2.13.54) ] || + skip "Need both MGS and MDS version at least 2.13.54" + + [ -d $MOUNT/.lustre ] || setupall + stack_trap "do_facet mds1 $LCTL set_param fail_loc=0" EXIT + + local device + local facet + local cmd + local orig_clist + local orig_count + local new_clist + local new_count + + for device in "MGS" "$FSNAME-MDT0000"; do + cmd="--device $device llog_catlist" + echo "lctl $cmd ..." + if [ "$device" = "MGS" ]; then + facet="mgs" + else + facet="mds1" + fi + orig_clist=($(do_facet $facet $LCTL $cmd | awk '{ print $2 }')) + orig_count=${#orig_clist[@]} + echo "orig_clist: ${orig_clist[@]}" + + #define OBD_FAIL_CATLIST 0x131b + #fetch to llog records from the second one + do_facet $facet $LCTL set_param fail_loc=0x131b fail_val=2 + + new_clist=($(do_facet $facet $LCTL $cmd | awk '{ print $2 }')) + new_count=${#new_clist[@]} + echo "new_clist: ${new_clist[@]}" + + [ $new_count -eq $((orig_count - 1)) ] || + error "$new_count != $orig_count - 1" + for i in $(seq 0 $new_count); do + j=$((i + 1)) + [ "${orig_clist[$j]}" = "${new_clist[$i]}" ] || + error "${orig_clist[$j]} != ${new_clist[$i]}" + done + do_facet mds1 $LCTL set_param fail_loc=0 + echo "done" + done +} +run_test 123af "llog_catlist can show all config files correctly" + test_123F() { remote_mgs_nodsh && skip "remote MGS with nodsh" diff --git a/lustre/utils/obd.c b/lustre/utils/obd.c index 9b1cc35..e824f24 100644 --- a/lustre/utils/obd.c +++ b/lustre/utils/obd.c @@ -2639,25 +2639,38 @@ int jt_llog_catlist(int argc, char **argv) { struct obd_ioctl_data data; char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; + char *tmp = NULL; + int start = 0; int rc; if (argc != 1) return CMD_HELP; - memset(&data, 0, sizeof(data)); - data.ioc_dev = cur_device; - data.ioc_inllen1 = sizeof(rawbuf) - __ALIGN_KERNEL(sizeof(data), 8); - memset(buf, 0, sizeof(rawbuf)); - rc = llapi_ioctl_pack(&data, &buf, sizeof(rawbuf)); - if (rc) { - fprintf(stderr, "error: %s: invalid ioctl\n", - jt_cmdname(argv[0])); - return rc; - } - rc = l_ioctl(OBD_DEV_ID, OBD_IOC_CATLOGLIST, buf); - if (rc == 0) - fprintf(stdout, "%s", ((struct obd_ioctl_data *)buf)->ioc_bulk); - else + do { + memset(&data, 0, sizeof(data)); + data.ioc_dev = cur_device; + data.ioc_inllen1 = sizeof(rawbuf) - + __ALIGN_KERNEL(sizeof(data), 8); + data.ioc_count = start; + memset(buf, 0, sizeof(rawbuf)); + rc = llapi_ioctl_pack(&data, &buf, sizeof(rawbuf)); + if (rc) { + fprintf(stderr, "error: %s: invalid ioctl\n", + jt_cmdname(argv[0])); + return rc; + } + rc = l_ioctl(OBD_DEV_ID, OBD_IOC_CATLOGLIST, buf); + if (rc < 0) + break; + tmp = ((struct obd_ioctl_data *)buf)->ioc_bulk; + if (strlen(tmp) > 0) + fprintf(stdout, "%s", tmp); + else + break; + start = ((struct obd_ioctl_data *)buf)->ioc_count; + } while (start); + + if (rc < 0) fprintf(stderr, "OBD_IOC_CATLOGLIST failed: %s\n", strerror(errno)); -- 1.8.3.1