Whamcloud - gitweb
LU-9153 utils: improve llog name parsing 68/25468/7
authorAndreas Dilger <andreas.dilger@intel.com>
Wed, 15 Feb 2017 06:28:39 +0000 (23:28 -0700)
committerOleg Drokin <oleg.drokin@intel.com>
Thu, 23 Mar 2017 01:41:44 +0000 (01:41 +0000)
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 <andreas.dilger@intel.com>
Change-Id: Idc00308162eb40b121b49bae3a6bc1d9326927fb
Reviewed-on: https://review.whamcloud.com/25468
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Henri Doreau <henri.doreau@cea.fr>
Reviewed-by: Nathaniel Clark <nathaniel.l.clark@intel.com>
Reviewed-by: John L. Hammond <john.hammond@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/doc/Makefile.am
lustre/doc/lctl-llog_catlist.8 [new file with mode: 0644]
lustre/doc/lctl-llog_info.8 [new file with mode: 0644]
lustre/doc/lctl-llog_print.8 [new file with mode: 0644]
lustre/doc/lctl.8
lustre/mgs/mgs_llog.c
lustre/obdclass/llog_ioctl.c
lustre/obdclass/obd_config.c
lustre/tests/sanity.sh
lustre/utils/lctl.c
lustre/utils/llog_reader.c

index faebfd1..de64846 100644 (file)
@@ -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 (file)
index 0000000..ec22a21
--- /dev/null
@@ -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 (file)
index 0000000..f5f9060
--- /dev/null
@@ -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 (file)
index 0000000..7230120
--- /dev/null
@@ -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)
index f29cce9..896386e 100644 (file)
@@ -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),
index 407667d..0c38f74 100644 (file)
@@ -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;
index da71aa8..ad53938 100644 (file)
 
 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)
index 1535999..84f8fb1 100644 (file)
@@ -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",
index b5e3a02..75bb587 100755 (executable)
@@ -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
index ea8fdd4..91e03cf 100644 (file)
@@ -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 <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]"},
index 890de00..7bd821e 100644 (file)
@@ -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)