+ * Get marker cfg_flag
+ */
+void llog_get_marker_cfg_flags(struct llog_rec_hdr *rec,
+ unsigned int *cfg_flags)
+{
+ struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
+ struct cfg_marker *marker;
+
+ if (lcfg->lcfg_command == LCFG_MARKER) {
+ marker = lustre_cfg_buf(lcfg, 1);
+ if (marker->cm_flags & CM_START) {
+ *cfg_flags = CFG_F_MARKER;
+ if (marker->cm_flags & CM_SKIP)
+ *cfg_flags = CFG_F_SKIP;
+ } else if (marker->cm_flags & CM_END) {
+ *cfg_flags = 0;
+ }
+ CDEBUG(D_INFO, "index=%d, cm_flags=%#08x cfg_flags=%#08x\n",
+ rec->lrh_index, marker->cm_flags, *cfg_flags);
+ }
+}
+
+/**
+ * Parse config record and output dump in supplied buffer.
+ *
+ * This is separated from class_config_dump_handler() to use
+ * for ioctl needs as well
+ *
+ * Sample Output:
+ * - { index: 4, event: attach, device: lustrewt-clilov, type: lov,
+ * UUID: lustrewt-clilov_UUID }
+ */
+int class_config_yaml_output(struct llog_rec_hdr *rec, char *buf, int size,
+ unsigned int *cfg_flags, bool raw)
+{
+ struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
+ char *ptr = buf;
+ char *end = buf + size;
+ int rc = 0, i;
+ struct lcfg_type_data *ldata;
+ int swab = 0;
+
+ LASSERT(rec->lrh_type == OBD_CFG_REC);
+
+ if (lcfg->lcfg_version == __swab32(LUSTRE_CFG_VERSION)) {
+ lustre_swab_lustre_cfg(lcfg);
+ swab = 1;
+ }
+
+ rc = lustre_cfg_sanity_check(lcfg, rec->lrh_len);
+ if (rc < 0)
+ return rc;
+
+ ldata = lcfg_cmd2data(lcfg->lcfg_command);
+ if (!ldata)
+ return -ENOTTY;
+
+ llog_get_marker_cfg_flags(rec, cfg_flags);
+ if ((lcfg->lcfg_command == LCFG_MARKER) && likely(!raw))
+ return 0;
+ /* entries outside marker are skipped */
+ if (!(*cfg_flags & CFG_F_MARKER) && !raw)
+ return 0;
+ /* inside skipped marker */
+ if ((*cfg_flags & CFG_F_SKIP) && !raw)
+ return 0;
+
+ /* form YAML entity */
+ ptr += snprintf(ptr, end - ptr, "- { index: %u, event: %s",
+ rec->lrh_index, ldata->ltd_name);
+ if (end - ptr <= 0)
+ goto out_overflow;
+
+ if (lcfg->lcfg_flags) {
+ ptr += snprintf(ptr, end - ptr, ", flags: %#08x",
+ lcfg->lcfg_flags);
+ if (end - ptr <= 0)
+ goto out_overflow;
+ }
+ if (lcfg->lcfg_num) {
+ ptr += snprintf(ptr, end - ptr, ", num: %#08x",
+ lcfg->lcfg_num);
+ if (end - ptr <= 0)
+ goto out_overflow;
+ }
+ if (lcfg->lcfg_nid) {
+ char nidstr[LNET_NIDSTR_SIZE];
+
+ libcfs_nid2str_r(lcfg->lcfg_nid, nidstr, sizeof(nidstr));
+ ptr += snprintf(ptr, end - ptr, ", nid: %s(%#llx)",
+ nidstr, lcfg->lcfg_nid);
+ if (end - ptr <= 0)
+ goto out_overflow;
+ }
+
+ if (LUSTRE_CFG_BUFLEN(lcfg, 0) > 0) {
+ ptr += snprintf(ptr, end - ptr, ", device: %s",
+ lustre_cfg_string(lcfg, 0));
+ if (end - ptr <= 0)
+ goto out_overflow;
+ }
+
+ if (lcfg->lcfg_command == LCFG_SET_PARAM) {
+ /*
+ * set_param -P parameters have param=val here, separate
+ * them through pointer magic and print them out in
+ * native yamlese
+ */
+ char *cfg_str = lustre_cfg_string(lcfg, 1);
+ char *tmp = strchr(cfg_str, '=');
+ size_t len;
+
+ if (!tmp)
+ goto out_done;
+
+ ptr += snprintf(ptr, end - ptr, ", %s: ", ldata->ltd_bufs[0]);
+ len = tmp - cfg_str + 1;
+ snprintf(ptr, len, "%s", cfg_str);
+ ptr += len - 1;
+
+ ptr += snprintf(ptr, end - ptr, ", %s: ", ldata->ltd_bufs[1]);
+ ptr += snprintf(ptr, end - ptr, "%s", tmp + 1);
+
+ goto out_done;
+ }
+
+ if (lcfg->lcfg_command == LCFG_MARKER) {
+ struct cfg_marker *marker;
+
+ marker = lustre_cfg_buf(lcfg, 1);
+ ptr += snprintf(ptr, end - ptr, ", flags: %#04x",
+ marker->cm_flags);
+ ptr += snprintf(ptr, end - ptr, ", version: %d.%d.%d.%d",
+ OBD_OCD_VERSION_MAJOR(marker->cm_vers),
+ OBD_OCD_VERSION_MINOR(marker->cm_vers),
+ OBD_OCD_VERSION_PATCH(marker->cm_vers),
+ OBD_OCD_VERSION_FIX(marker->cm_vers));
+ ptr += snprintf(ptr, end - ptr, ", createtime: %lld",
+ marker->cm_createtime);
+ ptr += snprintf(ptr, end - ptr, ", canceltime: %lld",
+ marker->cm_canceltime);
+
+ goto out_done;
+ }
+
+ for (i = 1; i < lcfg->lcfg_bufcount; i++) {
+ if (LUSTRE_CFG_BUFLEN(lcfg, i) > 0) {
+ ptr += snprintf(ptr, end - ptr, ", %s: %s",
+ ldata->ltd_bufs[i - 1],
+ lustre_cfg_string(lcfg, i));
+ if (end - ptr <= 0)
+ goto out_overflow;
+ }
+ }
+
+out_done:
+ ptr += snprintf(ptr, end - ptr, " }\n");
+out_overflow:
+ /* Return consumed bytes. If the buffer overflowed, zero last byte */
+ rc = ptr - buf;
+ if (rc > size) {
+ rc = -EOVERFLOW;
+ *(end - 1) = '\0';
+ }
+
+ return rc;
+}
+
+/**