Whamcloud - gitweb
LU-13609 llog: list all the log files correctly on MGS/MDT 17/38917/6
authorEmoly Liu <emoly@whamcloud.com>
Fri, 12 Jun 2020 08:12:00 +0000 (16:12 +0800)
committerOleg Drokin <green@whamcloud.com>
Sat, 4 Jul 2020 03:02:40 +0000 (03:02 +0000)
"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 <emoly@whamcloud.com>
Change-Id: I364d563446833751b1f017fa2bef0351dab56235
Reviewed-on: https://review.whamcloud.com/38917
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Ben Evans <beevans@whamcloud.com>
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/include/obd_support.h
lustre/mgs/mgs_llog.c
lustre/obdclass/llog_ioctl.c
lustre/tests/conf-sanity.sh
lustre/utils/obd.c

index 492c2b9..52960d8 100644 (file)
@@ -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_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
 
 #define OBD_FAIL_LLITE                              0x1400
 #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE             0x1401
index a8f8325..3025dfb 100644 (file)
@@ -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;
 {
        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;
 
 
        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;
 
        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) {
        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);
                                      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);
 }
 
        RETURN(rc);
 }
 
index 3db9ef5..894e2ea 100644 (file)
@@ -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;
 
        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",
                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;
                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);
 out:
        OBD_FREE_LARGE(idarray, size);
        RETURN(rc);
index 7cea4cb..3c6a42a 100644 (file)
@@ -8744,6 +8744,55 @@ test_123ae() { # LU-11566
 }
 run_test 123ae "llog_cancel can cancel requested record"
 
 }
 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"
 
 test_123F() {
        remote_mgs_nodsh && skip "remote MGS with nodsh"
 
index 9b1cc35..e824f24 100644 (file)
@@ -2639,25 +2639,38 @@ int jt_llog_catlist(int argc, char **argv)
 {
        struct obd_ioctl_data data;
        char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
 {
        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;
 
        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));
 
                fprintf(stderr, "OBD_IOC_CATLOGLIST failed: %s\n",
                        strerror(errno));