From a7a0e4070fba3091edc4921769fe36cb6262697d Mon Sep 17 00:00:00 2001 From: Andreas Dilger Date: Tue, 14 Feb 2017 23:28:39 -0700 Subject: [PATCH] LU-9153 utils: improve llog name parsing Current llog name specification is totally non-standard for lctl llog_print, llog_info, and related commands. Change this to accept llog names without the leading '$', since adding '$' is non-intuitive and the shell will think this is a variable and "$fsname-client" becomes "-client" unless it is escaped. Similarly, llog identifiers were formatted like "#0x4:10#0000000" instead of the standard FID format [0x4:0x10:0x0]. Update the code to accept and print FIDs in normal format. Add lctl-llog_print.8, lctl-llog_info.8, lctl-llog_catlist.8 man pages. Add a test case for parsing "lctl llog_print" with both old and new input formats. Signed-off-by: Andreas Dilger Change-Id: Idc00308162eb40b121b49bae3a6bc1d9326927fb Reviewed-on: https://review.whamcloud.com/25468 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Henri Doreau Reviewed-by: Nathaniel Clark Reviewed-by: John L. Hammond Reviewed-by: Oleg Drokin --- lustre/doc/Makefile.am | 3 ++ lustre/doc/lctl-llog_catlist.8 | 36 +++++++++++++++++ lustre/doc/lctl-llog_info.8 | 40 +++++++++++++++++++ lustre/doc/lctl-llog_print.8 | 70 ++++++++++++++++++++++++++++++++ lustre/doc/lctl.8 | 3 ++ lustre/mgs/mgs_llog.c | 2 +- lustre/obdclass/llog_ioctl.c | 91 ++++++++++++++++++++++++++---------------- lustre/obdclass/obd_config.c | 10 +++-- lustre/tests/sanity.sh | 18 ++++++++- lustre/utils/lctl.c | 14 +++---- lustre/utils/llog_reader.c | 6 +-- 11 files changed, 241 insertions(+), 52 deletions(-) create mode 100644 lustre/doc/lctl-llog_catlist.8 create mode 100644 lustre/doc/lctl-llog_info.8 create mode 100644 lustre/doc/lctl-llog_print.8 diff --git a/lustre/doc/Makefile.am b/lustre/doc/Makefile.am index faebfd1..de64846 100644 --- a/lustre/doc/Makefile.am +++ b/lustre/doc/Makefile.am @@ -111,6 +111,9 @@ SERVER_MANFILES = \ 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 \ diff --git a/lustre/doc/lctl-llog_catlist.8 b/lustre/doc/lctl-llog_catlist.8 new file mode 100644 index 0000000..ec22a21 --- /dev/null +++ b/lustre/doc/lctl-llog_catlist.8 @@ -0,0 +1,36 @@ +.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) diff --git a/lustre/doc/lctl-llog_info.8 b/lustre/doc/lctl-llog_info.8 new file mode 100644 index 0000000..f5f9060 --- /dev/null +++ b/lustre/doc/lctl-llog_info.8 @@ -0,0 +1,40 @@ +.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) diff --git a/lustre/doc/lctl-llog_print.8 b/lustre/doc/lctl-llog_print.8 new file mode 100644 index 0000000..7230120 --- /dev/null +++ b/lustre/doc/lctl-llog_print.8 @@ -0,0 +1,70 @@ +.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) diff --git a/lustre/doc/lctl.8 b/lustre/doc/lctl.8 index f29cce9..896386e 100644 --- a/lustre/doc/lctl.8 +++ b/lustre/doc/lctl.8 @@ -458,6 +458,9 @@ filesystem package. .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), diff --git a/lustre/mgs/mgs_llog.c b/lustre/mgs/mgs_llog.c index 407667d..0c38f74 100644 --- a/lustre/mgs/mgs_llog.c +++ b/lustre/mgs/mgs_llog.c @@ -4107,7 +4107,7 @@ int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs, 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; diff --git a/lustre/obdclass/llog_ioctl.c b/lustre/obdclass/llog_ioctl.c index da71aa8..ad53938 100644 --- a/lustre/obdclass/llog_ioctl.c +++ b/lustre/obdclass/llog_ioctl.c @@ -39,22 +39,38 @@ 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); @@ -82,6 +98,9 @@ static int str2logid(struct llog_logid *logid, char *str, int len) RETURN(-EINVAL); RETURN(0); +#else + RETURN(-EINVAL); +#endif } static int llog_check_cb(const struct lu_env *env, struct llog_handle *handle, @@ -132,8 +151,8 @@ 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); } @@ -213,8 +232,8 @@ static int llog_print_cb(const struct lu_env *env, struct llog_handle *handle, } 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; @@ -247,14 +266,15 @@ static int llog_remove_log(const struct lu_env *env, struct llog_handle *cat, 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); @@ -285,21 +305,24 @@ int llog_ioctl(const struct lu_env *env, struct llog_ctxt *ctxt, int cmd, 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); @@ -319,19 +342,19 @@ int llog_ioctl(const struct lu_env *env, struct llog_ctxt *ctxt, int cmd, 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); @@ -458,10 +481,8 @@ int llog_catalog_list(const struct lu_env *env, struct dt_device *d, 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) diff --git a/lustre/obdclass/obd_config.c b/lustre/obdclass/obd_config.c index 1535999..84f8fb1 100644 --- a/lustre/obdclass/obd_config.c +++ b/lustre/obdclass/obd_config.c @@ -1806,13 +1806,14 @@ static struct lcfg_type_data *lcfg_cmd2data(__u32 cmd) } /** - * 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) { @@ -1835,7 +1836,8 @@ 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", diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index b5e3a02..75bb587 100755 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -5378,7 +5378,23 @@ test_60a() { 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 diff --git a/lustre/utils/lctl.c b/lustre/utils/lctl.c index ea8fdd4..91e03cf 100644 --- a/lustre/utils/lctl.c +++ b/lustre/utils/lctl.c @@ -452,29 +452,27 @@ command_t cmdlist[] = { "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 \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 [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 [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 [log id] \n" + "llog_cancel [log id] \n" "usage (optional args): " "llog_cancel --catalog --log_id " "--log_idx "}, {"llog_remove", jt_llog_remove, 0, "remove one log from catalog or plain log, erase it from disk.\n" - "usage: llog_remove "}, + "usage: llog_remove "}, /* network operations */ {"add_interface", jt_ptl_add_interface, 0, "add interface entry\n" "usage: add_interface ip [netmask]"}, diff --git a/lustre/utils/llog_reader.c b/lustre/utils/llog_reader.c index 890de00..7bd821e 100644 --- a/lustre/utils/llog_reader.c +++ b/lustre/utils/llog_reader.c @@ -153,9 +153,9 @@ static void print_log_path(struct llog_logid_rec *lid, int is_ext) (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) -- 1.8.3.1