Whamcloud - gitweb
LU-1406 ofd: init lu_target in OFD
[fs/lustre-release.git] / lnet / utils / lst.c
index 1ffad47..60b29af 100644 (file)
@@ -1,7 +1,4 @@
 /*
- * -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
  * GPL HEADER START
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -17,8 +14,8 @@
  * in the LICENSE file that accompanied this code).
  *
  * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see [sun.com URL with a
- * copy of GPLv2].
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
  *
  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  * CA 95054 USA or visit www.sun.com if you need additional information or
@@ -27,7 +24,7 @@
  * GPL HEADER END
  */
 /*
- * Copyright  2008 Sun Microsystems, Inc. All rights reserved
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  */
 /*
 
 #define _GNU_SOURCE
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <getopt.h>
-#include <errno.h>
-#include <pwd.h>
+#include <libcfs/libcfsutil.h>
 #include <lnet/lnetctl.h>
 #include <lnet/lnetst.h>
-#include "parser.h"
 
-static command_t           lst_cmdlist[];
+
+lst_sid_t LST_INVALID_SID = {LNET_NID_ANY, -1};
 static lst_sid_t           session_id;
-static int                 session_key; 
+static int                 session_key;
 static lstcon_trans_stat_t trans_stat;
 
 typedef struct list_string {
@@ -62,7 +54,9 @@ typedef struct list_string {
         char                lstr_str[0];
 } lstr_t;
 
-#define offsetof(typ,memb)     ((unsigned long)((char *)&(((typ *)0)->memb)))
+#ifndef offsetof
+# define offsetof(typ,memb)     ((unsigned long)((char *)&(((typ *)0)->memb)))
+#endif
 
 static int alloc_count = 0;
 static int alloc_nob   = 0;
@@ -112,7 +106,7 @@ new_lstrs(lstr_t **list, char *prefix, char *postfix,
         int    n2 = strlen(postfix);
         int    sz = n1 + 20 + n2 + 1;
 
-        do { 
+        do {
                 lstr_t *n = alloc_lstr(sz);
 
                 snprintf(n->lstr_str, sz - 1, "%s%u%s",
@@ -136,9 +130,9 @@ expand_lstr(lstr_t **list, lstr_t *l)
         int          x;
         int          y;
         int          z;
-        int          n; 
+        int          n;
 
-        b1 = strchr(l->lstr_str, '[');  
+        b1 = strchr(l->lstr_str, '[');
         if (b1 == NULL) {
                 l->lstr_next = *list;
                 *list = l;
@@ -395,33 +389,33 @@ lst_print_error(char *sub, const char *def_format, ...)
 }
 
 void
-lst_free_rpcent(struct list_head *head)
+lst_free_rpcent(cfs_list_t *head)
 {
         lstcon_rpc_ent_t *ent;
 
-        while (!list_empty(head)) {
-                ent = list_entry(head->next, lstcon_rpc_ent_t, rpe_link);
+        while (!cfs_list_empty(head)) {
+                ent = cfs_list_entry(head->next, lstcon_rpc_ent_t, rpe_link);
 
-                list_del(&ent->rpe_link);
+                cfs_list_del(&ent->rpe_link);
                 free(ent);
         }
 }
 
 void
-lst_reset_rpcent(struct list_head *head)
+lst_reset_rpcent(cfs_list_t *head)
 {
         lstcon_rpc_ent_t *ent;
 
-        list_for_each_entry(ent, head, rpe_link) {
+        cfs_list_for_each_entry_typed(ent, head, lstcon_rpc_ent_t, rpe_link) {
                 ent->rpe_sid      = LST_INVALID_SID;
-                ent->rpe_peer.nid = LNET_NID_ANY; 
+                ent->rpe_peer.nid = LNET_NID_ANY;
                 ent->rpe_peer.pid = LNET_PID_ANY;
                 ent->rpe_rpc_errno = ent->rpe_fwk_errno = 0;
         }
 }
 
 int
-lst_alloc_rpcent(struct list_head *head, int count, int offset)
+lst_alloc_rpcent(cfs_list_t *head, int count, int offset)
 {
         lstcon_rpc_ent_t *ent;
         int               i;
@@ -436,20 +430,20 @@ lst_alloc_rpcent(struct list_head *head, int count, int offset)
                 memset(ent, 0, offsetof(lstcon_rpc_ent_t, rpe_payload[offset]));
 
                 ent->rpe_sid      = LST_INVALID_SID;
-                ent->rpe_peer.nid = LNET_NID_ANY; 
+                ent->rpe_peer.nid = LNET_NID_ANY;
                 ent->rpe_peer.pid = LNET_PID_ANY;
-                list_add(&ent->rpe_link, head);
+                cfs_list_add(&ent->rpe_link, head);
         }
 
         return 0;
 }
 
 void
-lst_print_transerr(struct list_head *head, char *optstr)
+lst_print_transerr(cfs_list_t *head, char *optstr)
 {
         lstcon_rpc_ent_t  *ent;
 
-        list_for_each_entry(ent, head, rpe_link) {
+        cfs_list_for_each_entry_typed(ent, head, lstcon_rpc_ent_t, rpe_link) {
                 if (ent->rpe_rpc_errno == 0 && ent->rpe_fwk_errno == 0)
                         continue;
 
@@ -460,7 +454,7 @@ lst_print_transerr(struct list_head *head, char *optstr)
                         continue;
                 }
 
-                fprintf(stderr, "%s failed on %s: %s\n", 
+                fprintf(stderr, "%s failed on %s: %s\n",
                         optstr, libcfs_id2str(ent->rpe_peer),
                         strerror(ent->rpe_fwk_errno));
         }
@@ -474,7 +468,7 @@ int lst_info_group_ioctl(char *name, lstcon_ndlist_ent_t *gent,
                          int *idx, int *count, lstcon_node_ent_t *dents);
 
 int lst_query_batch_ioctl(char *batch, int test, int server,
-                          int timeout, struct list_head *head);
+                          int timeout, cfs_list_t *head);
 
 int
 lst_ioctl(unsigned int opc, void *buf, int len)
@@ -511,14 +505,14 @@ lst_ioctl(unsigned int opc, void *buf, int len)
 int
 lst_new_session_ioctl (char *name, int timeout, int force, lst_sid_t *sid)
 {
-       lstio_session_new_args_t        args = {
-                .lstio_ses_key          = session_key,
-                .lstio_ses_timeout      = timeout,
-                .lstio_ses_force        = force,
-                .lstio_ses_idp          = sid,
-                .lstio_ses_namep        = name,
-                .lstio_ses_nmlen        = strlen(name),
-        };
+        lstio_session_new_args_t args = {0};
+
+        args.lstio_ses_key     = session_key;
+        args.lstio_ses_timeout = timeout;
+        args.lstio_ses_force   = force;
+        args.lstio_ses_idp     = sid;
+        args.lstio_ses_nmlen   = strlen(name);
+        args.lstio_ses_namep   = name;
 
         return lst_ioctl (LSTIO_SESSION_NEW, &args, sizeof(args));
 }
@@ -554,7 +548,7 @@ jt_lst_new_session(int argc,  char **argv)
 
                 if (c == -1)
                         break;
-        
+
                 switch (c) {
                 case 'f':
                         force = 1;
@@ -598,7 +592,7 @@ jt_lst_new_session(int argc,  char **argv)
                 snprintf(buf, LST_NAME_SIZE, "%s@%s", user, host);
                 name = buf;
 
-        } else { 
+        } else {
                 lst_print_usage(argv[0]);
                 return -1;
         }
@@ -621,13 +615,13 @@ int
 lst_session_info_ioctl(char *name, int len, int *key,
                        lst_sid_t *sid, lstcon_ndlist_ent_t *ndinfo)
 {
-        lstio_session_info_args_t args = {
-                .lstio_ses_keyp         = key,
-                .lstio_ses_idp          = sid,
-                .lstio_ses_ndinfo       = ndinfo,
-                .lstio_ses_nmlen        = len,
-                .lstio_ses_namep        = name,
-        };
+        lstio_session_info_args_t args = {0};
+
+        args.lstio_ses_idp    = sid;
+        args.lstio_ses_keyp   = key;
+        args.lstio_ses_ndinfo = ndinfo;
+        args.lstio_ses_nmlen  = len;
+        args.lstio_ses_namep  = name;
 
         return lst_ioctl(LSTIO_SESSION_INFO, &args, sizeof(args));
 }
@@ -649,7 +643,7 @@ jt_lst_show_session(int argc, char **argv)
                 return -1;
         }
 
-        fprintf(stdout, "%s ID: %Lu@%s, KEY: %d NODES: %d\n",
+        fprintf(stdout, "%s ID: "LPU64"@%s, KEY: %d NODES: %d\n",
                 name, sid.ses_stamp, libcfs_nid2str(sid.ses_nid),
                 key, ndinfo.nle_nnode);
 
@@ -659,10 +653,9 @@ jt_lst_show_session(int argc, char **argv)
 int
 lst_end_session_ioctl(void)
 {
-        lstio_session_end_args_t args = {
-                .lstio_ses_key           = session_key,
-        };
+        lstio_session_end_args_t args = {0};
 
+        args.lstio_ses_key =  session_key;
         return lst_ioctl (LSTIO_SESSION_END, &args, sizeof(args));
 }
 
@@ -708,20 +701,20 @@ jt_lst_end_session(int argc, char **argv)
 }
 
 int
-lst_ping_ioctl(char *str, int type, int timeout, 
-               int count, lnet_process_id_t *ids, struct list_head *head)
-{
-        lstio_debug_args_t args = {
-                .lstio_dbg_key          = session_key,
-                .lstio_dbg_type         = type,
-                .lstio_dbg_flags        = 0,
-                .lstio_dbg_timeout      = timeout,
-                .lstio_dbg_nmlen        = (str == NULL) ? 0: strlen(str),
-                .lstio_dbg_namep        = str,
-                .lstio_dbg_count        = count,
-                .lstio_dbg_idsp         = ids,
-                .lstio_dbg_resultp      = head,
-        };
+lst_ping_ioctl(char *str, int type, int timeout,
+               int count, lnet_process_id_t *ids, cfs_list_t *head)
+{
+        lstio_debug_args_t args = {0};
+
+        args.lstio_dbg_key     = session_key;
+        args.lstio_dbg_type    = type;
+        args.lstio_dbg_flags   = 0;
+        args.lstio_dbg_timeout = timeout;
+        args.lstio_dbg_nmlen   = (str == NULL) ? 0: strlen(str);
+        args.lstio_dbg_namep   = str;
+        args.lstio_dbg_count   = count;
+        args.lstio_dbg_idsp    = ids;
+        args.lstio_dbg_resultp = head;
 
         return lst_ioctl (LSTIO_DEBUG, &args, sizeof(args));
 }
@@ -747,7 +740,7 @@ lst_get_node_count(int type, char *str, int *countp, lnet_process_id_t **idspp)
         case LST_OPC_BATCHCLI:
                 rc = lst_info_batch_ioctl(str, 0, 0, &ent, NULL, NULL, NULL);
                 break;
-                
+
         case LST_OPC_GROUP:
                 rc = lst_info_group_ioctl(str, entp, NULL, NULL, NULL);
                 break;
@@ -761,7 +754,7 @@ lst_get_node_count(int type, char *str, int *countp, lnet_process_id_t **idspp)
                 break;
         }
 
-        if (rc == 0) 
+        if (rc == 0)
                 *countp = entp->nle_nnode;
 
         return rc;
@@ -770,7 +763,7 @@ lst_get_node_count(int type, char *str, int *countp, lnet_process_id_t **idspp)
 int
 jt_lst_ping(int argc,  char **argv)
 {
-        struct list_head   head;
+        cfs_list_t         head;
         lnet_process_id_t *ids = NULL;
         lstcon_rpc_ent_t  *ent = NULL;
         char              *str = NULL;
@@ -806,7 +799,7 @@ jt_lst_ping(int argc,  char **argv)
 
                 if (c == -1)
                         break;
-        
+
                 switch (c) {
                 case 's':
                         type = LST_OPC_SESSION;
@@ -880,7 +873,7 @@ jt_lst_ping(int argc,  char **argv)
         }
 
         /* ignore RPC errors and framwork errors */
-        list_for_each_entry(ent, &head, rpe_link) {
+        cfs_list_for_each_entry_typed(ent, &head, lstcon_rpc_ent_t, rpe_link) {
                 fprintf(stdout, "\t%s: %s [session: %s id: %s]\n",
                         libcfs_id2str(ent->rpe_peer),
                         lst_node_state2str(ent->rpe_state),
@@ -898,21 +891,21 @@ out:
                 free(ids);
 
         return rc;
-                
+
 }
 
 int
 lst_add_nodes_ioctl (char *name, int count, lnet_process_id_t *ids,
-                     struct list_head *resultp)
-{       
-        lstio_group_nodes_args_t        args = {
-                .lstio_grp_key          = session_key,
-                .lstio_grp_nmlen        = strlen(name),
-                .lstio_grp_namep        = name,
-                .lstio_grp_count        = count,
-                .lstio_grp_idsp         = ids,
-                .lstio_grp_resultp      = resultp,
-        };
+                     cfs_list_t *resultp)
+{
+        lstio_group_nodes_args_t args = {0};
+
+        args.lstio_grp_key     = session_key;
+        args.lstio_grp_nmlen   = strlen(name);
+        args.lstio_grp_namep   = name;
+        args.lstio_grp_count   = count;
+        args.lstio_grp_idsp    = ids;
+        args.lstio_grp_resultp = resultp;
 
         return lst_ioctl(LSTIO_NODES_ADD, &args, sizeof(args));
 }
@@ -920,11 +913,11 @@ lst_add_nodes_ioctl (char *name, int count, lnet_process_id_t *ids,
 int
 lst_add_group_ioctl (char *name)
 {
-        lstio_group_add_args_t  args = {
-                .lstio_grp_key          = session_key,
-                .lstio_grp_nmlen        = strlen(name),
-                .lstio_grp_namep        = name,
-        };
+        lstio_group_add_args_t args = {0};
+
+        args.lstio_grp_key     =  session_key;
+        args.lstio_grp_nmlen   =  strlen(name);
+        args.lstio_grp_namep   =  name;
 
         return lst_ioctl(LSTIO_GROUP_ADD, &args, sizeof(args));
 }
@@ -932,7 +925,7 @@ lst_add_group_ioctl (char *name)
 int
 jt_lst_add_group(int argc, char **argv)
 {
-        struct list_head   head;
+        cfs_list_t         head;
         lnet_process_id_t *ids;
         char              *name;
         int                count;
@@ -1011,11 +1004,11 @@ jt_lst_add_group(int argc, char **argv)
 int
 lst_del_group_ioctl (char *name)
 {
-        lstio_group_del_args_t  args = {
-                .lstio_grp_key          = session_key,
-                .lstio_grp_nmlen        = strlen(name),
-                .lstio_grp_namep        = name,
-        };
+        lstio_group_del_args_t args = {0};
+
+        args.lstio_grp_key   = session_key;
+        args.lstio_grp_nmlen = strlen(name);
+        args.lstio_grp_namep = name;
 
         return lst_ioctl(LSTIO_GROUP_DEL, &args, sizeof(args));
 }
@@ -1052,7 +1045,7 @@ jt_lst_del_group(int argc, char **argv)
 
         if (trans_stat.trs_rpc_errno != 0) {
                 fprintf(stderr, "[RPC] Failed to send %d end session RPCs: %s\n",
-                        lstcon_rpc_stat_failure(&trans_stat, 0), 
+                        lstcon_rpc_stat_failure(&trans_stat, 0),
                         strerror(trans_stat.trs_rpc_errno));
         }
 
@@ -1068,18 +1061,18 @@ jt_lst_del_group(int argc, char **argv)
 
 int
 lst_update_group_ioctl(int opc, char *name, int clean, int count,
-                       lnet_process_id_t *ids, struct list_head *resultp)
-{
-        lstio_group_update_args_t  args = {
-                .lstio_grp_key          = session_key,
-                .lstio_grp_opc          = opc,
-                .lstio_grp_args         = clean,
-                .lstio_grp_nmlen        = strlen(name),
-                .lstio_grp_namep        = name,
-                .lstio_grp_count        = count,
-                .lstio_grp_idsp         = ids,
-                .lstio_grp_resultp      = resultp,
-        };
+                       lnet_process_id_t *ids, cfs_list_t *resultp)
+{
+        lstio_group_update_args_t args = {0};
+
+        args.lstio_grp_key      = session_key;
+        args.lstio_grp_opc      = opc;
+        args.lstio_grp_args     = clean;
+        args.lstio_grp_nmlen    = strlen(name);
+        args.lstio_grp_namep    = name;
+        args.lstio_grp_count    = count;
+        args.lstio_grp_idsp     = ids;
+        args.lstio_grp_resultp  = resultp;
 
         return lst_ioctl(LSTIO_GROUP_UPDATE, &args, sizeof(args));
 }
@@ -1087,7 +1080,7 @@ lst_update_group_ioctl(int opc, char *name, int clean, int count,
 int
 jt_lst_update_group(int argc, char **argv)
 {
-        struct list_head   head;
+        cfs_list_t         head;
         lnet_process_id_t *ids = NULL;
         char              *str = NULL;
         char              *grp = NULL;
@@ -1119,7 +1112,7 @@ jt_lst_update_group(int argc, char **argv)
                 /* Detect the end of the options. */
                 if (c == -1)
                         break;
-        
+
                 switch (c) {
                 case 'f':
                         if (opc != 0) {
@@ -1183,7 +1176,7 @@ jt_lst_update_group(int argc, char **argv)
                         return -1;
                 }
 
-        } 
+        }
 
         rc = lst_update_group_ioctl(opc, grp, clean, count, ids, &head);
 
@@ -1212,12 +1205,12 @@ jt_lst_update_group(int argc, char **argv)
 int
 lst_list_group_ioctl(int len, char *name, int idx)
 {
-        lstio_group_list_args_t         args = {
-                .lstio_grp_key          = session_key,
-                .lstio_grp_idx          = idx,
-                .lstio_grp_nmlen        = len,
-                .lstio_grp_namep        = name,
-        };
+        lstio_group_list_args_t args = {0};
+
+        args.lstio_grp_key   = session_key;
+        args.lstio_grp_idx   = idx;
+        args.lstio_grp_nmlen = len;
+        args.lstio_grp_namep = name;
 
         return lst_ioctl(LSTIO_GROUP_LIST, &args, sizeof(args));
 }
@@ -1226,15 +1219,15 @@ int
 lst_info_group_ioctl(char *name, lstcon_ndlist_ent_t *gent,
                      int *idx, int *count, lstcon_node_ent_t *dents)
 {
-        lstio_group_info_args_t         args = {
-                .lstio_grp_key          = session_key,
-                .lstio_grp_nmlen        = strlen(name),
-                .lstio_grp_namep        = name,
-                .lstio_grp_entp         = gent,
-                .lstio_grp_idxp         = idx,
-                .lstio_grp_ndentp       = count,
-                .lstio_grp_dentsp       = dents,
-        };
+        lstio_group_info_args_t args = {0};
+
+        args.lstio_grp_key    = session_key;
+        args.lstio_grp_nmlen  = strlen(name);
+        args.lstio_grp_namep  = name;
+        args.lstio_grp_entp   = gent;
+        args.lstio_grp_idxp   = idx;
+        args.lstio_grp_ndentp = count;
+        args.lstio_grp_dentsp = dents;
 
         return lst_ioctl(LSTIO_GROUP_INFO, &args, sizeof(args));
 }
@@ -1254,7 +1247,7 @@ lst_list_group_all(void)
                         continue;
                 }
 
-                if (errno == ENOENT) 
+                if (errno == ENOENT)
                         break;
 
                 lst_print_error("group", "Failed to list group: %s\n",
@@ -1310,7 +1303,7 @@ jt_lst_list_group(int argc, char **argv)
 
                 if (c == -1)
                         break;
-        
+
                 switch (c) {
                 case 'a':
                         verbose = active = 1;
@@ -1418,27 +1411,27 @@ jt_lst_list_group(int argc, char **argv)
 
 int
 lst_stat_ioctl (char *name, int count, lnet_process_id_t *idsp,
-                int timeout, struct list_head *resultp)
-{
-        lstio_stat_args_t  args = {
-                .lstio_sta_key           = session_key,
-                .lstio_sta_timeout       = timeout,
-                .lstio_sta_nmlen         = strlen(name),
-                .lstio_sta_namep         = name,
-                .lstio_sta_count         = count,
-                .lstio_sta_idsp          = idsp,
-                .lstio_sta_resultp       = resultp,
-        };
+                int timeout, cfs_list_t *resultp)
+{
+        lstio_stat_args_t args = {0};
+
+        args.lstio_sta_key     = session_key;
+        args.lstio_sta_timeout = timeout;
+        args.lstio_sta_nmlen   = strlen(name);
+        args.lstio_sta_namep   = name;
+        args.lstio_sta_count   = count;
+        args.lstio_sta_idsp    = idsp;
+        args.lstio_sta_resultp = resultp;
 
         return lst_ioctl (LSTIO_STAT_QUERY, &args, sizeof(args));
 }
 
 typedef struct {
-        struct list_head        srp_link;
+        cfs_list_t              srp_link;
         int                     srp_count;
         char                   *srp_name;
         lnet_process_id_t      *srp_ids;
-        struct list_head        srp_result[2];
+        cfs_list_t              srp_result[2];
 } lst_stat_req_param_t;
 
 static void
@@ -1446,7 +1439,7 @@ lst_stat_req_param_free(lst_stat_req_param_t *srp)
 {
         int     i;
 
-        for (i = 0; i < 2; i++) 
+        for (i = 0; i < 2; i++)
                 lst_free_rpcent(&srp->srp_result[i]);
 
         if (srp->srp_ids != NULL)
@@ -1512,6 +1505,7 @@ lst_stat_req_param_alloc(char *name, lst_stat_req_param_t **srpp, int save_old)
 
 typedef struct {
         /* TODO */
+        int foo;
 } lst_srpc_stat_result;
 
 #define LST_LNET_AVG    0
@@ -1553,29 +1547,13 @@ lst_lnet_stat_value(int bw, int send, int off)
                  &lnet_stat_result.lnet_avg_sndrate;
 
         if (!send)
-                p += 4; 
+                p += 4;
 
         p += off;
 
         return *p;
 }
 
-static void
-lst_timeval_diff(struct timeval *tv1,
-                 struct timeval *tv2, struct timeval *df)
-{
-        if (tv1->tv_usec >= tv2->tv_usec) {
-                df->tv_sec  = tv1->tv_sec - tv2->tv_sec;
-                df->tv_usec = tv1->tv_usec - tv2->tv_usec;
-                return;
-        }
-
-        df->tv_sec  = tv1->tv_sec - 1 - tv2->tv_sec;
-        df->tv_usec = tv1->tv_sec + 1000000 - tv2->tv_usec;
-
-        return;
-}
-
 void
 lst_cal_lnet_stat(float delta, lnet_counters_t *lnet_new,
                   lnet_counters_t *lnet_old)
@@ -1695,10 +1673,10 @@ lst_print_lnet_stat(char *name, int bwrt, int rdwr, int type)
 }
 
 void
-lst_print_stat(char *name, struct list_head *resultp,
+lst_print_stat(char *name, cfs_list_t *resultp,
                int idx, int lnet, int bwrt, int rdwr, int type)
 {
-        struct list_head  tmp[2];
+        cfs_list_t        tmp[2];
         lstcon_rpc_ent_t *new;
         lstcon_rpc_ent_t *old;
         sfw_counters_t   *sfwk_new;
@@ -1707,7 +1685,6 @@ lst_print_stat(char *name, struct list_head *resultp,
         srpc_counters_t  *srpc_old;
         lnet_counters_t  *lnet_new;
         lnet_counters_t  *lnet_old;
-        struct timeval    tv;
         float             delta;
         int               errcount = 0;
 
@@ -1716,14 +1693,16 @@ lst_print_stat(char *name, struct list_head *resultp,
 
         memset(&lnet_stat_result, 0, sizeof(lnet_stat_result));
 
-        while (!list_empty(&resultp[idx])) {
-                if (list_empty(&resultp[1 - idx])) {
+        while (!cfs_list_empty(&resultp[idx])) {
+                if (cfs_list_empty(&resultp[1 - idx])) {
                         fprintf(stderr, "Group is changed, re-run stat\n");
                         break;
                 }
 
-                new = list_entry(resultp[idx].next, lstcon_rpc_ent_t, rpe_link);
-                old = list_entry(resultp[1 - idx].next, lstcon_rpc_ent_t, rpe_link);
+                new = cfs_list_entry(resultp[idx].next, lstcon_rpc_ent_t,
+                                     rpe_link);
+                old = cfs_list_entry(resultp[1 - idx].next, lstcon_rpc_ent_t,
+                                     rpe_link);
 
                 /* first time get stats result, can't calculate diff */
                 if (new->rpe_peer.nid == LNET_NID_ANY)
@@ -1735,11 +1714,11 @@ lst_print_stat(char *name, struct list_head *resultp,
                         break;
                 }
 
-                list_del(&new->rpe_link);
-                list_add_tail(&new->rpe_link, &tmp[idx]);
+                cfs_list_del(&new->rpe_link);
+                cfs_list_add_tail(&new->rpe_link, &tmp[idx]);
 
-                list_del(&old->rpe_link);
-                list_add_tail(&old->rpe_link, &tmp[1 - idx]);
+                cfs_list_del(&old->rpe_link);
+                cfs_list_add_tail(&old->rpe_link, &tmp[1 - idx]);
 
                 if (new->rpe_rpc_errno != 0 || new->rpe_fwk_errno != 0 ||
                     old->rpe_rpc_errno != 0 || old->rpe_fwk_errno != 0) {
@@ -1756,18 +1735,20 @@ lst_print_stat(char *name, struct list_head *resultp,
                 lnet_new = (lnet_counters_t *)((char *)srpc_new + sizeof(*srpc_new));
                 lnet_old = (lnet_counters_t *)((char *)srpc_old + sizeof(*srpc_old));
 
-                lst_timeval_diff(&new->rpe_stamp, &old->rpe_stamp, &tv);
+                /* use the timestamp from the remote node, not our rpe_stamp
+                 * from when we copied up the data out of the kernel */
 
-                delta = tv.tv_sec + (float)tv.tv_usec/1000000;
+                delta = (float) (sfwk_new->running_ms -
+                                 sfwk_old->running_ms) / 1000;
 
                 if (!lnet) /* TODO */
                         continue;
-                
+
                 lst_cal_lnet_stat(delta, lnet_new, lnet_old);
         }
 
-        list_splice(&tmp[idx], &resultp[idx]);
-        list_splice(&tmp[1 - idx], &resultp[1 - idx]);
+        cfs_list_splice(&tmp[idx], &resultp[idx]);
+        cfs_list_splice(&tmp[1 - idx], &resultp[1 - idx]);
 
         if (errcount > 0)
                 fprintf(stdout, "Failed to stat on %d nodes\n", errcount);
@@ -1781,12 +1762,13 @@ lst_print_stat(char *name, struct list_head *resultp,
 int
 jt_lst_stat(int argc, char **argv)
 {
-        struct list_head      head;
+        cfs_list_t            head;
         lst_stat_req_param_t *srp;
         time_t                last    = 0;
         int                   optidx  = 0;
         int                   timeout = 5; /* default timeout, 5 sec */
         int                   delay   = 5; /* default delay, 5 sec */
+        int                   count   = -1; /* run forever */
         int                   lnet    = 1; /* lnet stat by default */
         int                   bwrt    = 0;
         int                   rdwr    = 0;
@@ -1799,6 +1781,7 @@ jt_lst_stat(int argc, char **argv)
         {
                 {"timeout", required_argument, 0, 't' },
                 {"delay"  , required_argument, 0, 'd' },
+                {"count"  , required_argument, 0, 'o' },
                 {"lnet"   , no_argument,       0, 'l' },
                 {"rpc"    , no_argument,       0, 'c' },
                 {"bw"     , no_argument,       0, 'b' },
@@ -1822,7 +1805,7 @@ jt_lst_stat(int argc, char **argv)
 
                 if (c == -1)
                         break;
-        
+
                 switch (c) {
                 case 't':
                         timeout = atoi(optarg);
@@ -1830,6 +1813,9 @@ jt_lst_stat(int argc, char **argv)
                 case 'd':
                         delay = atoi(optarg);
                         break;
+                case 'o':
+                        count = atoi(optarg);
+                        break;
                 case 'l':
                         lnet = 1;
                         break;
@@ -1885,19 +1871,28 @@ jt_lst_stat(int argc, char **argv)
                 return -1;
         }
 
+        if (count < -1) {
+            fprintf(stderr, "Invalid count value\n");
+            return -1;
+        }
+
+        /* extra count to get first data point */
+        if (count != -1)
+            count++;
+
         CFS_INIT_LIST_HEAD(&head);
 
         while (optind < argc) {
                 rc = lst_stat_req_param_alloc(argv[optind++], &srp, 1);
-                if (rc != 0) 
+                if (rc != 0)
                         goto out;
 
-                list_add_tail(&srp->srp_link, &head);
+                cfs_list_add_tail(&srp->srp_link, &head);
         }
 
-        while (1) {
+        do {
                 time_t  now = time(NULL);
-        
+
                 if (now - last < delay) {
                         sleep(delay - now + last);
                         time(&now);
@@ -1905,7 +1900,8 @@ jt_lst_stat(int argc, char **argv)
 
                 last = now;
 
-                list_for_each_entry(srp, &head, srp_link) {
+                cfs_list_for_each_entry_typed(srp, &head, lst_stat_req_param_t,
+                                              srp_link) {
                         rc = lst_stat_ioctl(srp->srp_name,
                                             srp->srp_count, srp->srp_ids,
                                             timeout, &srp->srp_result[idx]);
@@ -1922,13 +1918,16 @@ jt_lst_stat(int argc, char **argv)
                 }
 
                 idx = 1 - idx;
-        }
+
+                if (count > 0)
+                        count--;
+        } while (count == -1 || count > 0);
 
 out:
-        while (!list_empty(&head)) {
-                srp = list_entry(head.next, lst_stat_req_param_t, srp_link);
+        while (!cfs_list_empty(&head)) {
+                srp = cfs_list_entry(head.next, lst_stat_req_param_t, srp_link);
 
-                list_del(&srp->srp_link);
+                cfs_list_del(&srp->srp_link);
                 lst_stat_req_param_free(srp);
         }
 
@@ -1938,7 +1937,7 @@ out:
 int
 jt_lst_show_error(int argc, char **argv)
 {
-        struct list_head      head;
+        cfs_list_t            head;
         lst_stat_req_param_t *srp;
         lstcon_rpc_ent_t     *ent;
         sfw_counters_t       *sfwk;
@@ -1955,7 +1954,7 @@ jt_lst_show_error(int argc, char **argv)
                 {"session", no_argument,       0, 's' },
                 {0,         0,                 0,  0  }
         };
+
         if (session_key == 0) {
                 fprintf(stderr,
                         "Can't find env LST_SESSION or value is not valid\n");
@@ -1967,7 +1966,7 @@ jt_lst_show_error(int argc, char **argv)
 
                 if (c == -1)
                         break;
-        
+
                 switch (c) {
                 case 's':
                         show_rpc  = 0;
@@ -1978,7 +1977,7 @@ jt_lst_show_error(int argc, char **argv)
                         return -1;
                 }
         }
+
         if (optind == argc) {
                 lst_print_usage(argv[0]);
                 return -1;
@@ -1988,15 +1987,16 @@ jt_lst_show_error(int argc, char **argv)
 
         while (optind < argc) {
                 rc = lst_stat_req_param_alloc(argv[optind++], &srp, 0);
-                if (rc != 0) 
+                if (rc != 0)
                         goto out;
 
-                list_add_tail(&srp->srp_link, &head);
+                cfs_list_add_tail(&srp->srp_link, &head);
         }
 
-        list_for_each_entry(srp, &head, srp_link) {
+        cfs_list_for_each_entry_typed(srp, &head, lst_stat_req_param_t,
+                                      srp_link) {
                 rc = lst_stat_ioctl(srp->srp_name, srp->srp_count,
-                                    srp->srp_ids, 5, &srp->srp_result[0]);
+                                    srp->srp_ids, 10, &srp->srp_result[0]);
 
                 if (rc == -1) {
                         lst_print_error(srp->srp_name, "Failed to show errors of %s: %s\n",
@@ -2008,7 +2008,8 @@ jt_lst_show_error(int argc, char **argv)
 
                 ecount = 0;
 
-                list_for_each_entry(ent, &srp->srp_result[0], rpe_link) {
+                cfs_list_for_each_entry_typed(ent, &srp->srp_result[0],
+                                              lstcon_rpc_ent_t, rpe_link) {
                         if (ent->rpe_rpc_errno != 0) {
                                 ecount ++;
                                 fprintf(stderr, "RPC failure, can't show error on %s\n",
@@ -2031,14 +2032,14 @@ jt_lst_show_error(int argc, char **argv)
                             sfwk->brw_errors == 0 && sfwk->ping_errors == 0)
                                 continue;
 
-                        if (!show_rpc  && 
+                        if (!show_rpc  &&
                             sfwk->brw_errors == 0 && sfwk->ping_errors == 0)
                                 continue;
-        
+
                         ecount ++;
 
                         fprintf(stderr, "%s: [Session %d brw errors, %d ping errors]%c",
-                                libcfs_id2str(ent->rpe_peer), 
+                                libcfs_id2str(ent->rpe_peer),
                                 sfwk->brw_errors, sfwk->ping_errors,
                                 show_rpc  ? ' ' : '\n');
 
@@ -2048,14 +2049,14 @@ jt_lst_show_error(int argc, char **argv)
                         fprintf(stderr, "[RPC: %d errors, %d dropped, %d expired]\n",
                                 srpc->errors, srpc->rpcs_dropped, srpc->rpcs_expired);
                 }
-        
+
                 fprintf(stdout, "Total %d error nodes in %s\n", ecount, srp->srp_name);
         }
 out:
-        while (!list_empty(&head)) {
-                srp = list_entry(head.next, lst_stat_req_param_t, srp_link);
+        while (!cfs_list_empty(&head)) {
+                srp = cfs_list_entry(head.next, lst_stat_req_param_t, srp_link);
 
-                list_del(&srp->srp_link);
+                cfs_list_del(&srp->srp_link);
                 lst_stat_req_param_free(srp);
         }
 
@@ -2065,11 +2066,11 @@ out:
 int
 lst_add_batch_ioctl (char *name)
 {
-        lstio_batch_add_args_t  args = {
-                .lstio_bat_key           = session_key,
-                .lstio_bat_nmlen         = strlen(name),
-                .lstio_bat_namep         = name,
-        };
+        lstio_batch_add_args_t args = {0};
+
+        args.lstio_bat_key   = session_key;
+        args.lstio_bat_nmlen = strlen(name);
+        args.lstio_bat_namep = name;
 
         return lst_ioctl (LSTIO_BATCH_ADD, &args, sizeof(args));
 }
@@ -2091,7 +2092,7 @@ jt_lst_add_batch(int argc, char **argv)
                 return -1;
         }
 
-        name = argv[1];        
+        name = argv[1];
         if (strlen(name) >= LST_NAME_SIZE) {
                 fprintf(stderr, "Name length is limited to %d\n",
                         LST_NAME_SIZE - 1);
@@ -2109,15 +2110,15 @@ jt_lst_add_batch(int argc, char **argv)
 }
 
 int
-lst_start_batch_ioctl (char *name, int timeout, struct list_head *resultp)
-{
-        lstio_batch_run_args_t   args = {
-                .lstio_bat_key          = session_key,
-                .lstio_bat_timeout      = timeout,
-                .lstio_bat_nmlen        = strlen(name),
-                .lstio_bat_namep        = name,
-                .lstio_bat_resultp      = resultp,
-        };
+lst_start_batch_ioctl (char *name, int timeout, cfs_list_t *resultp)
+{
+        lstio_batch_run_args_t args = {0};
+
+        args.lstio_bat_key     = session_key;
+        args.lstio_bat_timeout = timeout;
+        args.lstio_bat_nmlen   = strlen(name);
+        args.lstio_bat_namep   = name;
+        args.lstio_bat_resultp = resultp;
 
         return lst_ioctl(LSTIO_BATCH_START, &args, sizeof(args));
 }
@@ -2125,7 +2126,7 @@ lst_start_batch_ioctl (char *name, int timeout, struct list_head *resultp)
 int
 jt_lst_start_batch(int argc, char **argv)
 {
-        struct list_head  head;
+        cfs_list_t        head;
         char             *batch;
         int               optidx  = 0;
         int               timeout = 0;
@@ -2152,7 +2153,7 @@ jt_lst_start_batch(int argc, char **argv)
                 /* Detect the end of the options. */
                 if (c == -1)
                         break;
-        
+
                 switch (c) {
                 case 't':
                         timeout = atoi(optarg);
@@ -2162,7 +2163,7 @@ jt_lst_start_batch(int argc, char **argv)
                         return -1;
                 }
         }
-       
+
         if (optind == argc) {
                 batch = LST_DEFAULT_BATCH;
 
@@ -2212,15 +2213,15 @@ jt_lst_start_batch(int argc, char **argv)
 }
 
 int
-lst_stop_batch_ioctl(char *name, int force, struct list_head *resultp)
-{       
-        lstio_batch_stop_args_t   args = {
-                .lstio_bat_key          = session_key,
-                .lstio_bat_force        = force,
-                .lstio_bat_nmlen        = strlen(name),
-                .lstio_bat_namep        = name,
-                .lstio_bat_resultp      = resultp,
-        };
+lst_stop_batch_ioctl(char *name, int force, cfs_list_t *resultp)
+{
+        lstio_batch_stop_args_t args = {0};
+
+        args.lstio_bat_key     = session_key;
+        args.lstio_bat_force   = force;
+        args.lstio_bat_nmlen   = strlen(name);
+        args.lstio_bat_namep   = name;
+        args.lstio_bat_resultp = resultp;
 
         return lst_ioctl(LSTIO_BATCH_STOP, &args, sizeof(args));
 }
@@ -2228,7 +2229,7 @@ lst_stop_batch_ioctl(char *name, int force, struct list_head *resultp)
 int
 jt_lst_stop_batch(int argc, char **argv)
 {
-        struct list_head  head;
+        cfs_list_t        head;
         char             *batch;
         int               force = 0;
         int               optidx;
@@ -2255,7 +2256,7 @@ jt_lst_stop_batch(int argc, char **argv)
                 /* Detect the end of the options. */
                 if (c == -1)
                         break;
-        
+
                 switch (c) {
                 case 'f':
                         force = 1;
@@ -2334,12 +2335,12 @@ out:
 int
 lst_list_batch_ioctl(int len, char *name, int index)
 {
-        lstio_batch_list_args_t         args = {
-                .lstio_bat_key          = session_key,
-                .lstio_bat_idx          = index,
-                .lstio_bat_nmlen        = len,
-                .lstio_bat_namep        = name,
-        };
+        lstio_batch_list_args_t args = {0};
+
+        args.lstio_bat_key   = session_key;
+        args.lstio_bat_idx   = index;
+        args.lstio_bat_nmlen = len;
+        args.lstio_bat_namep = name;
 
         return lst_ioctl(LSTIO_BATCH_LIST, &args, sizeof(args));
 }
@@ -2349,17 +2350,17 @@ lst_info_batch_ioctl(char *batch, int test, int server,
                      lstcon_test_batch_ent_t *entp, int *idxp,
                      int *ndentp, lstcon_node_ent_t *dentsp)
 {
-        lstio_batch_info_args_t         args = {
-                .lstio_bat_key          = session_key,
-                .lstio_bat_nmlen        = strlen(batch),
-                .lstio_bat_namep        = batch,
-                .lstio_bat_server       = server,
-                .lstio_bat_testidx      = test,
-                .lstio_bat_entp         = entp,
-                .lstio_bat_idxp         = idxp,
-                .lstio_bat_ndentp       = ndentp,
-                .lstio_bat_dentsp       = dentsp,
-        };
+        lstio_batch_info_args_t args = {0};
+
+        args.lstio_bat_key     = session_key;
+        args.lstio_bat_nmlen   = strlen(batch);
+        args.lstio_bat_namep   = batch;
+        args.lstio_bat_server  = server;
+        args.lstio_bat_testidx = test;
+        args.lstio_bat_entp    = entp;
+        args.lstio_bat_idxp    = idxp;
+        args.lstio_bat_ndentp  = ndentp;
+        args.lstio_bat_dentsp  = dentsp;
 
         return lst_ioctl(LSTIO_BATCH_INFO, &args, sizeof(args));
 }
@@ -2378,7 +2379,7 @@ lst_list_batch_all(void)
                         continue;
                 }
 
-                if (errno == ENOENT) 
+                if (errno == ENOENT)
                         break;
 
                 lst_print_error("batch", "Failed to list batch: %s\n",
@@ -2401,7 +2402,7 @@ lst_list_tsb_nodes(char *batch, int test, int server,
         int                c;
         int                i;
 
-        if (count == 0) 
+        if (count == 0)
                 return 0;
 
         /* verbose list, show nodes in batch or test */
@@ -2426,7 +2427,7 @@ lst_list_tsb_nodes(char *batch, int test, int server,
                 if ((!active  && dents[i].nde_state == LST_NODE_ACTIVE) ||
                     (!invalid && (dents[i].nde_state == LST_NODE_BUSY  ||
                                   dents[i].nde_state == LST_NODE_DOWN  ||
-                                  dents[i].nde_state == LST_NODE_UNKNOWN))) 
+                                  dents[i].nde_state == LST_NODE_UNKNOWN)))
                         continue;
 
                 fprintf(stdout, "\t%s: %s\n",
@@ -2434,7 +2435,7 @@ lst_list_tsb_nodes(char *batch, int test, int server,
                         lst_node_state2str(dents[i].nde_state));
                 c++;
         }
-      
+
         fprintf(stdout, "Total %d nodes\n", c);
         free(dents);
 
@@ -2478,7 +2479,7 @@ jt_lst_list_batch(int argc, char **argv)
 
                 if (c == -1)
                         break;
-        
+
                 switch (c) {
                 case 'a':
                         verbose = active = 1;
@@ -2517,7 +2518,7 @@ jt_lst_list_batch(int argc, char **argv)
                 lst_print_usage(argv[0]);
                 return -1;
         }
-                
+
         batch = argv[optind];
 
 loop:
@@ -2562,7 +2563,7 @@ loop:
         fprintf(stdout, LST_NODES_TITLE);
         fprintf(stdout, "client\t%d\t%d\t%d\t%d\t%d\n"
                         "server\t%d\t%d\t%d\t%d\t%d\n",
-                ent.tbe_cli_nle.nle_nactive, 
+                ent.tbe_cli_nle.nle_nactive,
                 ent.tbe_cli_nle.nle_nbusy,
                 ent.tbe_cli_nle.nle_ndown,
                 ent.tbe_cli_nle.nle_nunknown,
@@ -2581,28 +2582,28 @@ loop:
 
 int
 lst_query_batch_ioctl(char *batch, int test, int server,
-                      int timeout, struct list_head *head)
-{
-        lstio_batch_query_args_t args = {
-                .lstio_bat_key     = session_key,
-                .lstio_bat_testidx = test,
-                .lstio_bat_client  = !(server),
-                .lstio_bat_timeout = timeout,
-                .lstio_bat_nmlen   = strlen(batch),
-                .lstio_bat_namep   = batch,
-                .lstio_bat_resultp = head,
-        };
+                      int timeout, cfs_list_t *head)
+{
+        lstio_batch_query_args_t args = {0};
+
+        args.lstio_bat_key     = session_key;
+        args.lstio_bat_testidx = test;
+        args.lstio_bat_client  = !(server);
+        args.lstio_bat_timeout = timeout;
+        args.lstio_bat_nmlen   = strlen(batch);
+        args.lstio_bat_namep   = batch;
+        args.lstio_bat_resultp = head;
 
         return lst_ioctl(LSTIO_BATCH_QUERY, &args, sizeof(args));
 }
 
 void
-lst_print_tsb_verbose(struct list_head *head,
+lst_print_tsb_verbose(cfs_list_t *head,
                       int active, int idle, int error)
 {
         lstcon_rpc_ent_t *ent;
 
-        list_for_each_entry(ent, head, rpe_link) {
+        cfs_list_for_each_entry_typed(ent, head, lstcon_rpc_ent_t, rpe_link) {
                 if (ent->rpe_priv[0] == 0 && active)
                         continue;
 
@@ -2625,23 +2626,23 @@ int
 jt_lst_query_batch(int argc, char **argv)
 {
         lstcon_test_batch_ent_t ent;
-        struct list_head     head;
-        char                *batch   = NULL;
-        time_t               last    = 0;
-        int                  optidx  = 0;
-        int                  verbose = 0;
-        int                  server  = 0;
-        int                  timeout = 5; /* default 5 seconds */
-        int                  delay   = 5; /* default 5 seconds */
-        int                  loop    = 1; /* default 1 loop */
-        int                  active  = 0;
-        int                  error   = 0;
-        int                  idle    = 0;
-        int                  count   = 0;
-        int                  test    = 0;
-        int                  rc      = 0;
-        int                  c       = 0;
-        int                  i;
+        cfs_list_t              head;
+        char                   *batch   = NULL;
+        time_t                  last    = 0;
+        int                     optidx  = 0;
+        int                     verbose = 0;
+        int                     server  = 0;
+        int                     timeout = 5; /* default 5 seconds */
+        int                     delay   = 5; /* default 5 seconds */
+        int                     loop    = 1; /* default 1 loop */
+        int                     active  = 0;
+        int                     error   = 0;
+        int                     idle    = 0;
+        int                     count   = 0;
+        int                     test    = 0;
+        int                     rc      = 0;
+        int                     c       = 0;
+        int                     i;
 
         static struct option query_batch_opts[] =
         {
@@ -2670,7 +2671,7 @@ jt_lst_query_batch(int argc, char **argv)
                 /* Detect the end of the options. */
                 if (c == -1)
                         break;
-        
+
                 switch (c) {
                 case 'o':
                         timeout = atoi(optarg);
@@ -2749,7 +2750,7 @@ jt_lst_query_batch(int argc, char **argv)
 
         for (i = 0; i < loop; i++) {
                 time_t  now = time(NULL);
-        
+
                 if (now - last < delay) {
                         sleep(delay - now + last);
                         time(&now);
@@ -2803,7 +2804,7 @@ jt_lst_query_batch(int argc, char **argv)
 
         return rc;
 }
-         
+
 int
 lst_parse_distribute(char *dstr, int *dist, int *span)
 {
@@ -2812,7 +2813,7 @@ lst_parse_distribute(char *dstr, int *dist, int *span)
                 return -1;
 
         dstr = strchr(dstr, ':');
-        if (dstr == NULL) 
+        if (dstr == NULL)
                 return -1;
 
         *span = atoi(dstr + 1);
@@ -2847,7 +2848,7 @@ lst_get_bulk_param(int argc, char **argv, lst_test_bulk_param_t *bulk)
                                 fprintf(stderr, "Unknow flag %s\n", tok);
                                 return -1;
                         }
-                                
+
                 } else if (strcasestr(argv[i], "size=") == argv[i] ||
                          strcasestr(argv[i], "s=") == argv[i]) {
                         tok = strchr(argv[i], '=') + 1;
@@ -2871,11 +2872,11 @@ lst_get_bulk_param(int argc, char **argv, lst_test_bulk_param_t *bulk)
                                         bulk->blk_size);
                                 return -1;
                         }
-                        
+
                 } else if (strcasecmp(argv[i], "read") == 0 ||
                            strcasecmp(argv[i], "r") == 0) {
                         bulk->blk_opc = LST_BRW_READ;
-                
+
                 } else if (strcasecmp(argv[i], "write") == 0 ||
                            strcasecmp(argv[i], "w") == 0) {
                         bulk->blk_opc = LST_BRW_WRITE;
@@ -2929,7 +2930,7 @@ lst_get_test_param(char *test, int argc, char **argv, void **param, int *plen)
         default:
                 break;
         }
-        
+
         /* TODO: parse more parameter */
         return type;
 }
@@ -2937,26 +2938,27 @@ lst_get_test_param(char *test, int argc, char **argv, void **param, int *plen)
 int
 lst_add_test_ioctl(char *batch, int type, int loop, int concur,
                    int dist, int span, char *sgrp, char *dgrp,
-                   void *param, int plen, int *retp, struct list_head *resultp)
-{
-        lstio_test_args_t args = {
-                .lstio_tes_key          = session_key,
-                .lstio_tes_bat_nmlen    = strlen(batch),
-                .lstio_tes_bat_name     = batch,
-                .lstio_tes_type         = type,
-                .lstio_tes_loop         = loop,
-                .lstio_tes_concur       = concur,
-                .lstio_tes_dist         = dist,
-                .lstio_tes_span         = span,
-                .lstio_tes_sgrp_nmlen   = strlen(sgrp),
-                .lstio_tes_sgrp_name    = sgrp,
-                .lstio_tes_dgrp_nmlen   = strlen(dgrp),
-                .lstio_tes_dgrp_name    = dgrp,
-                .lstio_tes_param_len    = plen,
-                .lstio_tes_param        = param,
-                .lstio_tes_retp         = retp,
-                .lstio_tes_resultp      = resultp,
-        };
+                   void *param, int plen, int *retp, cfs_list_t *resultp)
+{
+        lstio_test_args_t args = {0};
+
+        args.lstio_tes_key        = session_key;
+        args.lstio_tes_bat_nmlen  = strlen(batch);
+        args.lstio_tes_bat_name   = batch;
+        args.lstio_tes_type       = type;
+        args.lstio_tes_oneside    = 0;
+        args.lstio_tes_loop       = loop;
+        args.lstio_tes_concur     = concur;
+        args.lstio_tes_dist       = dist;
+        args.lstio_tes_span       = span;
+        args.lstio_tes_sgrp_nmlen = strlen(sgrp);
+        args.lstio_tes_sgrp_name  = sgrp;
+        args.lstio_tes_dgrp_nmlen = strlen(dgrp);
+        args.lstio_tes_dgrp_name  = dgrp;
+        args.lstio_tes_param_len  = plen;
+        args.lstio_tes_param      = param;
+        args.lstio_tes_retp       = retp;
+        args.lstio_tes_resultp    = resultp;
 
         return lst_ioctl(LSTIO_TEST_ADD, &args, sizeof(args));
 }
@@ -2964,25 +2966,25 @@ lst_add_test_ioctl(char *batch, int type, int loop, int concur,
 int
 jt_lst_add_test(int argc, char **argv)
 {
-        struct list_head  head;
-        char             *batch  = NULL;
-        char             *test   = NULL;
-        char             *dstr   = NULL;
-        char             *from   = NULL;
-        char             *to     = NULL;
-        void             *param  = NULL;
-        int               optidx = 0;
-        int               concur = 1;
-        int               loop   = -1;
-        int               dist   = 1;
-        int               span   = 1;
-        int               plen   = 0;
-        int               fcount = 0;
-        int               tcount = 0;
-        int               ret    = 0;
-        int               type;
-        int               rc;
-        int               c;
+        cfs_list_t    head;
+        char         *batch  = NULL;
+        char         *test   = NULL;
+        char         *dstr   = NULL;
+        char         *from   = NULL;
+        char         *to     = NULL;
+        void         *param  = NULL;
+        int           optidx = 0;
+        int           concur = 1;
+        int           loop   = -1;
+        int           dist   = 1;
+        int           span   = 1;
+        int           plen   = 0;
+        int           fcount = 0;
+        int           tcount = 0;
+        int           ret    = 0;
+        int           type;
+        int           rc;
+        int           c;
 
         static struct option add_test_opts[] =
         {
@@ -3008,7 +3010,7 @@ jt_lst_add_test(int argc, char **argv)
                 /* Detect the end of the options. */
                 if (c == -1)
                         break;
-        
+
                 switch (c) {
                 case 'b':
                         batch = optarg;
@@ -3137,7 +3139,7 @@ static command_t lst_cmdlist[] = {
           "Usage: lst list_group [--active] [--busy] [--down] [--unknown] GROUP ..."    },
         {"stat",                jt_lst_stat,            NULL,
          "Usage: lst stat [--bw] [--rate] [--read] [--write] [--max] [--min] [--avg] "
-         " [--timeout #] [--delay #] GROUP [GROUP]"                                     },
+         " [--timeout #] [--delay #] [--count #] GROUP [GROUP]"                         },
         {"show_error",          jt_lst_show_error,      NULL,
          "Usage: lst show_error NAME | IDS ..."                                         },
         {"add_batch",           jt_lst_add_batch,       NULL,
@@ -3177,20 +3179,32 @@ lst_initialize(void)
 int
 main(int argc, char **argv)
 {
+        int rc = 0;
+
         setlinebuf(stdout);
 
-        if (lst_initialize() < 0)
-                exit(0);
+        rc = libcfs_arch_init();
+        if (rc < 0)
+                return rc;
+
+        rc = lst_initialize();
+        if (rc < 0)
+                goto errorout;
 
-        if (ptl_initialize(argc, argv) < 0)
-                exit(0);
+        rc = ptl_initialize(argc, argv);
+        if (rc < 0)
+                goto errorout;
         
         Parser_init("lst > ", lst_cmdlist);
 
-        if (argc != 1) 
-                return Parser_execarg(argc - 1, argv + 1, lst_cmdlist);
+        if (argc != 1)  {
+                rc = Parser_execarg(argc - 1, argv + 1, lst_cmdlist);
+                goto errorout;
+        }
 
         Parser_commands();
 
-        return 0;
+errorout:
+        libcfs_arch_cleanup();
+        return rc;
 }