lctl-lfsck-query.8 \
lctl-lfsck-start.8 \
lctl-lfsck-stop.8 \
+ lctl-llog_catlist.8 \
+ lctl-llog_info.8 \
+ lctl-llog_print.8 \
lctl-nodemap-activate.8 \
lctl-nodemap-add.8 \
lctl-nodemap-add-idmap.8 \
--- /dev/null
+.TH lctl-llog_catlist 8 "2017 Feb 24" Lustre "configuration utilities"
+.SH NAME
+lctl llog_catlist \- list Lustre configuration log files
+.SH SYNOPSIS
+.B lctl llog_catlist
+
+.SH DESCRIPTION
+.B lctl llog_catlist
+is used to list the configuration log files on the MGS, or other target.
+This is useful to find the names of all the configuration files available.
+.SH EXAMPLES
+.TP
+To list all of the records on the MGS:
+.br
+# lctl --device MGS llog_catlist
+.br
+config_log: testfs-OST0000
+.br
+config_log: testfs-MDT0000
+.br
+config_log: testfs-client
+.br
+config_log: params-client
+.br
+config_log: testfs-OST0001
+.SH AVAILABILITY
+.B lctl llog_catlist
+is a subcommand of
+.BR lctl (8)
+and is distributed as part of the
+.BR lustre (7)
+filesystem package.
+.SH SEE ALSO
+.BR lctl (8)
+.BR lctl-llog_info (8)
+.BR lctl-llog_print (8)
--- /dev/null
+.TH lctl-llog_info 8 "2017 Feb 24" Lustre "configuration utilities"
+.SH NAME
+lctl llog_info \- print information about a Lustre configuration log
+.SH SYNOPSIS
+.B lctl llog_info
+.RI < logname >
+
+.SH DESCRIPTION
+.B lctl llog_info
+is used to print information about the configuration log given by
+.IR logname .
+.SH OPTIONS
+.B logname
+The name of the configuration log, in the form
+.IR fsname - target ,
+like
+.B testfs-client
+or
+.BR lustrefs-MDT0000 .
+.SH EXAMPLES
+.TP
+To print all of the records from the testfs-client configuration log:
+.br
+# lctl --device MGS llog_info testfs-client
+.br
+logid: [0x4:0xa:0x0]:0
+flags: 4 (plain)
+records_count: 48
+last_index: 47
+.SH AVAILABILITY
+.B lctl llog_info
+is a subcommand of
+.BR lctl (8)
+and is distributed as part of the
+.BR lustre (7)
+filesystem package.
+.SH SEE ALSO
+.BR lctl (8)
+.BR lctl-llog_catlist (8)
+.BR lctl-llog_print (8)
--- /dev/null
+.TH lctl-llog_print 8 "2017 Feb 24" Lustre "configuration utilities"
+.SH NAME
+lctl llog_print \- print the content of a configuration log
+.SH SYNOPSIS
+.B lctl llog_print
+.RI < logname >
+.RI [ start_index ]
+.RI [ end_index ]
+
+.SH DESCRIPTION
+.B lctl llog_print
+is used to dump the contents of the
+.I logname
+configuration log on the MGS in YAML format. This is useful for debugging
+configuration problems and to list any permanent configuration options
+saved via
+.B lctl conf_param
+on the MGS.
+.SH OPTIONS
+.TP
+.B logname
+The name of the configuration log, in the form
+.IR fsname - target ,
+like
+.B testfs-client
+or
+.BR lustrefs-MDT0000 .
+.TP
+.B start_index
+The first record number in the config log to dump. Note that deactivated
+records and comment records will not be printed.
+.TP
+.B end_index
+The last record number in the config log to dump.
+.SH EXAMPLES
+.TP
+To print all of the records from the testfs-client configuration log:
+.br
+# lctl --device MGS llog_print testfs-client
+.br
+- { index: 3, event: attach, device: testfs-clilov, type: lov,
+.br
+ UUID: testfs-clilov_UUID }
+.br
+- { index: 6, event: setup, device: testfs-clilov, UUID: }
+.br
+- { index: 9, event: attach, device: testfs-clilmv, type: lov,
+.br
+ UUID: testfs-clilmv_UUID }
+.br
+- { index: 12, event: setup, device: testfs-clilmv, UUID: }
+.br
+- { index: 15, add_uuid: nid: 10.211.55.6@tcp(0x200000ad33706),
+.br
+ node: 10.211.55.6@tcp }
+.br
+:
+.br
+:
+.SH AVAILABILITY
+.B lctl llog_print
+is a subcommand of
+.BR lctl (8)
+and is distributed as part of the
+.BR lustre (7)
+filesystem package.
+.SH SEE ALSO
+.BR lctl (8)
+.BR lctl-llog_info (8)
+.BR lctl-llog_catlist (8)
.BR lctl-lfsck-start (8),
.BR lctl-lfsck-stop (8),
.BR lctl-lfsck-query (8),
+.BR lctl-llog_catlist (8),
+.BR lctl-llog_info (8),
+.BR lctl-llog_print (8),
.BR lctl-network (8),
.BR lctl-nodemap-activate (8),
.BR lctl-nodemap-add-idmap (8),
list_del_init(&dirent->mde_list);
suffix = strrchr(dirent->mde_name, '-');
if (suffix != NULL) {
- l = snprintf(out, remains, "config log: $%s\n",
+ l = snprintf(out, remains, "config_log: %s\n",
dirent->mde_name);
out += l;
remains -= l;
static int str2logid(struct llog_logid *logid, char *str, int len)
{
- char *start, *end, *endp;
+ char *start, *end, *endp;
__u64 id, seq;
- ENTRY;
- start = str;
- if (*start != '#')
- RETURN(-EINVAL);
+ ENTRY;
+ start = str;
+ if (start[0] == '[') {
+ struct lu_fid *fid = &logid->lgl_oi.oi_fid;
+ int num;
+
+ fid_zero(fid);
+ logid->lgl_ogen = 0;
+ num = sscanf(start + 1, SFID, RFID(fid));
+ CDEBUG(D_INFO, DFID":%x\n", PFID(fid), logid->lgl_ogen);
+ RETURN(num == 3 && fid_is_sane(fid) ? 0 : -EINVAL);
+ }
- start++;
- if (start - str >= len - 1)
- RETURN(-EINVAL);
- end = strchr(start, '#');
- if (end == NULL || end == start)
- RETURN(-EINVAL);
+#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 1, 53, 0)
+ /* logids used to be input in the form "#id#seq:ogen" before they
+ * were changed over to accept the FID [seq:oid:ver] format.
+ * This is accepted for compatibility reasons, though I doubt
+ * anyone is actually using this for anything. */
+ if (start[0] != '#')
+ RETURN(-EINVAL);
- *end = '\0';
+ start++;
+ if (start - str >= len - 1)
+ RETURN(-EINVAL);
+ end = strchr(start, '#');
+ if (end == NULL || end == start)
+ RETURN(-EINVAL);
+
+ *end = '\0';
id = simple_strtoull(start, &endp, 0);
if (endp != end)
RETURN(-EINVAL);
RETURN(-EINVAL);
RETURN(0);
+#else
+ RETURN(-EINVAL);
+#endif
}
static int llog_check_cb(const struct lu_env *env, struct llog_handle *handle,
RETURN(-EOPNOTSUPP);
rc = llog_cat_id2handle(env, handle, &loghandle, &lir->lid_id);
if (rc) {
- CDEBUG(D_IOCTL, "cannot find log #"DOSTID"#%08x\n",
- POSTID(&lir->lid_id.lgl_oi),
+ CDEBUG(D_IOCTL, "cannot find log "DFID":%x\n",
+ PFID(&lir->lid_id.lgl_oi.oi_fid),
lir->lid_id.lgl_ogen);
RETURN(rc);
}
}
l = snprintf(out, remains,
- "[index]: %05d [logid]: #"DOSTID"#%08x\n",
- cur_index, POSTID(&lir->lid_id.lgl_oi),
+ "[index]: %05d [logid]: "DFID":%x\n",
+ cur_index, PFID(&lir->lid_id.lgl_oi.oi_fid),
lir->lid_id.lgl_ogen);
} else if (rec->lrh_type == OBD_CFG_REC) {
int rc;
rc = llog_cat_id2handle(env, cat, &log, logid);
if (rc) {
- CDEBUG(D_IOCTL, "cannot find log #"DOSTID"#%08x\n",
- POSTID(&logid->lgl_oi), logid->lgl_ogen);
+ CDEBUG(D_IOCTL, "cannot find log "DFID":%x\n",
+ PFID(&logid->lgl_oi.oi_fid), logid->lgl_ogen);
RETURN(-ENOENT);
}
rc = llog_destroy(env, log);
if (rc) {
- CDEBUG(D_IOCTL, "cannot destroy log\n");
+ CDEBUG(D_IOCTL, "cannot destroy log "DFID":%x\n",
+ PFID(&logid->lgl_oi.oi_fid), logid->lgl_ogen);
GOTO(out, rc);
}
llog_cat_cleanup(env, cat, log, log->u.phd.phd_cookie.lgc_index);
struct llog_logid logid;
int rc = 0;
struct llog_handle *handle = NULL;
+ char *logname;
ENTRY;
- if (*data->ioc_inlbuf1 == '#') {
- rc = str2logid(&logid, data->ioc_inlbuf1, data->ioc_inllen1);
+ logname = data->ioc_inlbuf1;
+ if (logname[0] == '#' || logname[0] == '[') {
+ rc = str2logid(&logid, logname, data->ioc_inllen1);
if (rc)
RETURN(rc);
rc = llog_open(env, ctxt, &handle, &logid, NULL,
LLOG_OPEN_EXISTS);
if (rc)
RETURN(rc);
- } else if (*data->ioc_inlbuf1 == '$') {
- char *name = data->ioc_inlbuf1 + 1;
+ } else if (logname[0] == '$' || isalpha(logname[0])) {
+ if (logname[0] == '$')
+ logname++;
- rc = llog_open(env, ctxt, &handle, NULL, name,
+ rc = llog_open(env, ctxt, &handle, NULL, logname,
LLOG_OPEN_EXISTS);
if (rc)
RETURN(rc);
char *out = data->ioc_bulk;
l = snprintf(out, remains,
- "logid: #"DOSTID"#%08x\n"
+ "logid: "DFID":%x\n"
"flags: %x (%s)\n"
- "records count: %d\n"
- "last index: %d\n",
- POSTID(&handle->lgh_id.lgl_oi),
+ "records_count: %d\n"
+ "last_index: %d\n",
+ PFID(&handle->lgh_id.lgl_oi.oi_fid),
handle->lgh_id.lgl_ogen,
handle->lgh_hdr->llh_flags,
handle->lgh_hdr->llh_flags &
- LLOG_F_IS_CAT ? "cat" : "plain",
+ LLOG_F_IS_CAT ? "cat" : "plain",
handle->lgh_hdr->llh_count,
handle->lgh_last_idx);
- out += l;
- remains -= l;
+ out += l;
+ remains -= l;
if (remains <= 0) {
CERROR("%s: not enough space for log header info\n",
ctxt->loc_obd->obd_name);
remains = data->ioc_inllen1;
for (i = 0; i < count; i++) {
id = &idarray[i].lci_logid;
- l = snprintf(out, remains,
- "catalog log: #"DOSTID"#%08x\n",
- POSTID(&id->lgl_oi),
- id->lgl_ogen);
+ l = snprintf(out, remains, "catalog_log: "DFID":%x\n",
+ PFID(&id->lgl_oi.oi_fid), id->lgl_ogen);
out += l;
remains -= l;
if (remains <= 0)
}
/**
- * parse config record and output dump in supplied buffer.
+ * 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:
- * - { event: attach, device: lustrewt-clilov, type: lov, UUID:
- * lustrewt-clilov_UUID }
+ * - { 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)
{
return 0;
/* form YAML entity */
- ptr += snprintf(ptr, end - ptr, "- { event: %s", ldata->ltd_name);
+ ptr += snprintf(ptr, end - ptr, "- { index: %u, event: %s",
+ rec->lrh_index, ldata->ltd_name);
if (lcfg->lcfg_flags)
ptr += snprintf(ptr, end - ptr, ", flags: %#08x",
start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
$pass || error "test failed, see FAILED test_60a messages for specifics"
}
-run_test 60a "llog_test run from kernel module and test llog_reader =========="
+run_test 60a "llog_test run from kernel module and test llog_reader"
+
+test_60aa() {
+ # test old logid format
+ if [ $(lustre_version_code mgs) -le $(version_code 3.1.53) ]; then
+ do_facet mgs $LCTL dl | grep MGS
+ do_facet mgs "$LCTL --device %MGS llog_print \\\\\\\$$FSNAME-client" ||
+ error "old llog_print failed"
+ fi
+
+ # test new logid format
+ if [ $(lustre_version_code mgs) -ge $(version_code 2.9.53) ]; then
+ do_facet mgs "$LCTL --device MGS llog_print $FSNAME-client" ||
+ error "new llog_print failed"
+ fi
+}
+run_test 60aa "llog_print works with FIDs and simple names"
test_60b() { # bug 6411
[ $PARALLEL == "yes" ] && skip "skip parallel run" && return
"usage: llog_catlist"},
{"llog_info", jt_llog_info, 0,
"print log header information.\n"
- "usage: llog_info <$logname|#oid#ogr#ogen>\n"
+ "usage: llog_info <logname|[FID]>\n"
" oid, ogr and ogen are hexadecimal."},
{"llog_print", jt_llog_print, 0,
"print log content information.\n"
- "usage: llog_print <$logname|#oid#ogr#ogen> [from] [to]\n"
- " oid, ogr and ogen are hexadecimal.\n"
+ "usage: llog_print <logname|[FID]> [start_index [end_index]]\n"
" print all records from index 1 by default."},
{"llog_check", jt_llog_check, 0,
"print log content information.\n"
- "usage: llog_check <$logname|#oid#ogr#ogen> [from] [to]\n"
- " oid, ogr and ogen are hexadecimal.\n"
+ "usage: llog_check <logname|[FID]> [start_index] [end_index]\n"
" check all records from index 1 by default."},
- {"llog_cancel", jt_llog_cancel, 0,
+ {"llog_cancel", jt_llog_cancel, 0,
"cancel one record in log.\n"
"This command supports both positional and optional arguments\n"
"usage (positional args): "
- "llog_cancel <catalog id|catalog name> [log id] <index>\n"
+ "llog_cancel <catalog name|[FID]> [log id] <index>\n"
"usage (optional args): "
"llog_cancel --catalog <catalog id|catalog name> --log_id <log_id> "
"--log_idx <index>"},
{"llog_remove", jt_llog_remove, 0,
"remove one log from catalog or plain log, erase it from disk.\n"
- "usage: llog_remove <catalog id|catalog name> <log id>"},
+ "usage: llog_remove <catalog name|[FID]> <log id>"},
/* network operations */
{"add_interface", jt_ptl_add_interface, 0, "add interface entry\n"
"usage: add_interface ip [netmask]"},
(uintmax_t)(fid_from_logid.f_seq & (OSD_OI_FID_NR - 1)),
PFID(&fid_from_logid));
- printf("ogen=%X id="DOSTID" path=%s\n",
- lid->lid_id.lgl_ogen, POSTID(&lid->lid_id.lgl_oi),
- object_path);
+ printf("id="DFID":%x path=%s\n",
+ PFID(&lid->lid_id.lgl_oi.oi_fid), lid->lid_id.lgl_ogen,
+ object_path);
}
int main(int argc, char **argv)