@@ -84,8 +84,6 @@ struct lst_sid {
__s64 ses_stamp; /* time stamp */
}; /*** session id */
-extern struct lst_sid LST_INVALID_SID;
-
struct lst_bid {
__u64 bat_id; /* unique id in session */
}; /*** batch id (group of tests) */
@@ -577,4 +575,23 @@ struct sfw_counters {
__u32 ping_errors;
} __packed;
+#define LNET_SELFTEST_GENL_NAME "lnet_selftest"
+#define LNET_SELFTEST_GENL_VERSION 0x1
+
+/* enum lnet_selftest_commands - Supported core LNet Selftest Netlink
+ * commands
+ *
+ * @LNET_SELFTEST_CMD_UNSPEC: unspecified command to catch errors
+ * @LNET_SELFTEST_CMD_SESSIONS: command to manage sessions
+ */
+enum lnet_selftest_commands {
+ LNET_SELFTEST_CMD_UNSPEC = 0,
+
+ LNET_SELFTEST_CMD_SESSIONS = 1,
+
+ __LNET_SELFTEST_CMD_MAX_PLUS_ONE,
+};
+
+#define LNET_SELFTEST_CMD_MAX (__LNET_SELFTEST_CMD_MAX_PLUS_ONE - 1)
+
#endif
@@ -40,67 +40,6 @@
#include "console.h"
static int
-lst_session_new_ioctl(struct lstio_session_new_args *args)
-{
- char name[LST_NAME_SIZE + 1];
- int rc;
-
- if (!args->lstio_ses_idp || /* address for output sid */
- !args->lstio_ses_key || /* no key is specified */
- !args->lstio_ses_namep || /* session name */
- args->lstio_ses_nmlen <= 0 ||
- args->lstio_ses_nmlen > LST_NAME_SIZE)
- return -EINVAL;
-
- if (copy_from_user(name, args->lstio_ses_namep,
- args->lstio_ses_nmlen)) {
- return -EFAULT;
- }
-
- name[args->lstio_ses_nmlen] = 0;
-
- rc = lstcon_session_new(name,
- args->lstio_ses_key,
- args->lstio_ses_feats,
- args->lstio_ses_timeout,
- args->lstio_ses_force,
- args->lstio_ses_idp);
-
- return rc;
-}
-
-static int
-lst_session_end_ioctl(struct lstio_session_end_args *args)
-{
- if (args->lstio_ses_key != console_session.ses_key)
- return -EACCES;
-
- return lstcon_session_end();
-}
-
-static int
-lst_session_info_ioctl(struct lstio_session_info_args *args)
-{
- /* no checking of key */
-
- if (!args->lstio_ses_idp || /* address for output sid */
- !args->lstio_ses_keyp || /* address for output key */
- !args->lstio_ses_featp || /* address for output features */
- !args->lstio_ses_ndinfo || /* address for output ndinfo */
- !args->lstio_ses_namep || /* address for output name */
- args->lstio_ses_nmlen <= 0 ||
- args->lstio_ses_nmlen > LST_NAME_SIZE)
- return -EINVAL;
-
- return lstcon_session_info(args->lstio_ses_idp,
- args->lstio_ses_keyp,
- args->lstio_ses_featp,
- args->lstio_ses_ndinfo,
- args->lstio_ses_namep,
- args->lstio_ses_nmlen);
-}
-
-static int
lst_debug_ioctl(struct lstio_debug_args *args)
{
char name[LST_NAME_SIZE + 1];
@@ -729,13 +668,11 @@ static int lst_test_add_ioctl(struct lstio_test_args *args)
switch (opc) {
case LSTIO_SESSION_NEW:
- rc = lst_session_new_ioctl((struct lstio_session_new_args *)buf);
- break;
+ fallthrough;
case LSTIO_SESSION_END:
- rc = lst_session_end_ioctl((struct lstio_session_end_args *)buf);
- break;
+ fallthrough;
case LSTIO_SESSION_INFO:
- rc = lst_session_info_ioctl((struct lstio_session_info_args *)buf);
+ rc = -EOPNOTSUPP;
break;
case LSTIO_DEBUG:
rc = lst_debug_ioctl((struct lstio_debug_args *)buf);
@@ -797,3 +734,283 @@ static int lst_test_add_ioctl(struct lstio_test_args *args)
return notifier_from_ioctl_errno(rc);
}
+
+static struct genl_family lst_family;
+
+static const struct ln_key_list lst_session_keys = {
+ .lkl_maxattr = LNET_SELFTEST_SESSION_MAX,
+ .lkl_list = {
+ [LNET_SELFTEST_SESSION_HDR] = {
+ .lkp_value = "session",
+ .lkp_key_format = LNKF_MAPPING,
+ .lkp_data_type = NLA_NUL_STRING,
+ },
+ [LNET_SELFTEST_SESSION_NAME] = {
+ .lkp_value = "name",
+ .lkp_data_type = NLA_STRING,
+ },
+ [LNET_SELFTEST_SESSION_KEY] = {
+ .lkp_value = "key",
+ .lkp_data_type = NLA_U32,
+ },
+ [LNET_SELFTEST_SESSION_TIMESTAMP] = {
+ .lkp_value = "timestamp",
+ .lkp_data_type = NLA_S64,
+ },
+ [LNET_SELFTEST_SESSION_NID] = {
+ .lkp_value = "nid",
+ .lkp_data_type = NLA_STRING,
+ },
+ [LNET_SELFTEST_SESSION_NODE_COUNT] = {
+ .lkp_value = "nodes",
+ .lkp_data_type = NLA_U16,
+ },
+ },
+};
+
+static int lst_sessions_show_dump(struct sk_buff *msg,
+ struct netlink_callback *cb)
+{
+ const struct ln_key_list *all[] = {
+ &lst_session_keys, NULL
+ };
+ struct netlink_ext_ack *extack = cb->extack;
+ int portid = NETLINK_CB(cb->skb).portid;
+ int seq = cb->nlh->nlmsg_seq;
+ unsigned int node_count = 0;
+ struct lstcon_ndlink *ndl;
+ int flag = NLM_F_MULTI;
+ int rc = 0;
+ void *hdr;
+
+ if (console_session.ses_state != LST_SESSION_ACTIVE) {
+ NL_SET_ERR_MSG(extack, "session is not active");
+ rc = -ESRCH;
+ goto out_unlock;
+ }
+
+ list_for_each_entry(ndl, &console_session.ses_ndl_list, ndl_link)
+ node_count++;
+
+ rc = lnet_genl_send_scalar_list(msg, portid, seq, &lst_family,
+ NLM_F_CREATE | NLM_F_MULTI,
+ LNET_SELFTEST_CMD_SESSIONS, all);
+ if (rc < 0) {
+ NL_SET_ERR_MSG(extack, "failed to send key table");
+ goto out_unlock;
+ }
+
+ if (console_session.ses_force)
+ flag |= NLM_F_REPLACE;
+
+ hdr = genlmsg_put(msg, portid, seq, &lst_family, flag,
+ LNET_SELFTEST_CMD_SESSIONS);
+ if (!hdr) {
+ NL_SET_ERR_MSG(extack, "failed to send values");
+ genlmsg_cancel(msg, hdr);
+ rc = -EMSGSIZE;
+ goto out_unlock;
+ }
+
+ nla_put_string(msg, LNET_SELFTEST_SESSION_NAME,
+ console_session.ses_name);
+ nla_put_u32(msg, LNET_SELFTEST_SESSION_KEY,
+ console_session.ses_key);
+ nla_put_u64_64bit(msg, LNET_SELFTEST_SESSION_TIMESTAMP,
+ console_session.ses_id.ses_stamp,
+ LNET_SELFTEST_SESSION_PAD);
+ nla_put_string(msg, LNET_SELFTEST_SESSION_NID,
+ libcfs_nidstr(&console_session.ses_id.ses_nid));
+ nla_put_u16(msg, LNET_SELFTEST_SESSION_NODE_COUNT,
+ node_count);
+ genlmsg_end(msg, hdr);
+out_unlock:
+ return rc;
+}
+
+static int lst_sessions_cmd(struct sk_buff *skb, struct genl_info *info)
+{
+ struct sk_buff *msg = NULL;
+ int rc = 0;
+
+ mutex_lock(&console_session.ses_mutex);
+
+ console_session.ses_laststamp = ktime_get_real_seconds();
+
+ if (console_session.ses_shutdown) {
+ GENL_SET_ERR_MSG(info, "session is shutdown");
+ rc = -ESHUTDOWN;
+ goto out_unlock;
+ }
+
+ if (console_session.ses_expired)
+ lstcon_session_end();
+
+ if (!(info->nlhdr->nlmsg_flags & NLM_F_CREATE) &&
+ console_session.ses_state == LST_SESSION_NONE) {
+ GENL_SET_ERR_MSG(info, "session is not active");
+ rc = -ESRCH;
+ goto out_unlock;
+ }
+
+ memset(&console_session.ses_trans_stat, 0,
+ sizeof(struct lstcon_trans_stat));
+
+ if (!(info->nlhdr->nlmsg_flags & NLM_F_CREATE)) {
+ lstcon_session_end();
+ goto out_unlock;
+ }
+
+ if (info->attrs[LN_SCALAR_ATTR_LIST]) {
+ struct genlmsghdr *gnlh = nlmsg_data(info->nlhdr);
+ const struct ln_key_list *all[] = {
+ &lst_session_keys, NULL
+ };
+ char name[LST_NAME_SIZE];
+ struct nlmsghdr *nlh;
+ struct nlattr *item;
+ bool force = false;
+ s64 timeout = 300;
+ void *hdr;
+ int rem;
+
+ if (info->nlhdr->nlmsg_flags & NLM_F_REPLACE)
+ force = true;
+
+ nla_for_each_nested(item, info->attrs[LN_SCALAR_ATTR_LIST],
+ rem) {
+ if (nla_type(item) != LN_SCALAR_ATTR_VALUE)
+ continue;
+
+ if (nla_strcmp(item, "name") == 0) {
+ ssize_t len;
+
+ item = nla_next(item, &rem);
+ if (nla_type(item) != LN_SCALAR_ATTR_VALUE) {
+ rc = -EINVAL;
+ goto err_conf;
+ }
+
+ len = nla_strlcpy(name, item, sizeof(name));
+ if (len < 0)
+ rc = len;
+ } else if (nla_strcmp(item, "timeout") == 0) {
+ item = nla_next(item, &rem);
+ if (nla_type(item) !=
+ LN_SCALAR_ATTR_INT_VALUE) {
+ rc = -EINVAL;
+ goto err_conf;
+ }
+
+ timeout = nla_get_s64(item);
+ if (timeout < 0)
+ rc = -ERANGE;
+ }
+ if (rc < 0) {
+err_conf:
+ GENL_SET_ERR_MSG(info,
+ "failed to get config");
+ goto out_unlock;
+ }
+ }
+
+ rc = lstcon_session_new(name, info->nlhdr->nlmsg_pid,
+ gnlh->version, timeout,
+ force);
+ if (rc < 0) {
+ GENL_SET_ERR_MSG(info, "new session creation failed");
+ lstcon_session_end();
+ goto out_unlock;
+ }
+
+ msg = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
+ if (!msg) {
+ GENL_SET_ERR_MSG(info, "msg allocation failed");
+ rc = -ENOMEM;
+ goto out_unlock;
+ }
+
+ rc = lnet_genl_send_scalar_list(msg, info->snd_portid,
+ info->snd_seq, &lst_family,
+ NLM_F_CREATE | NLM_F_MULTI,
+ LNET_SELFTEST_CMD_SESSIONS,
+ all);
+ if (rc < 0) {
+ GENL_SET_ERR_MSG(info, "failed to send key table");
+ goto out_unlock;
+ }
+
+ hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq,
+ &lst_family, NLM_F_MULTI,
+ LNET_SELFTEST_CMD_SESSIONS);
+ if (!hdr) {
+ GENL_SET_ERR_MSG(info, "failed to send values");
+ genlmsg_cancel(msg, hdr);
+ rc = -EMSGSIZE;
+ goto out_unlock;
+ }
+
+ nla_put_string(msg, LNET_SELFTEST_SESSION_NAME,
+ console_session.ses_name);
+ nla_put_u32(msg, LNET_SELFTEST_SESSION_KEY,
+ console_session.ses_key);
+ nla_put_u64_64bit(msg, LNET_SELFTEST_SESSION_TIMESTAMP,
+ console_session.ses_id.ses_stamp,
+ LNET_SELFTEST_SESSION_PAD);
+ nla_put_string(msg, LNET_SELFTEST_SESSION_NID,
+ libcfs_nidstr(&console_session.ses_id.ses_nid));
+ nla_put_u16(msg, LNET_SELFTEST_SESSION_NODE_COUNT, 0);
+
+ genlmsg_end(msg, hdr);
+
+ nlh = nlmsg_put(msg, info->snd_portid, info->snd_seq,
+ NLMSG_DONE, 0, NLM_F_MULTI);
+ if (!nlh) {
+ GENL_SET_ERR_MSG(info, "failed to complete message");
+ genlmsg_cancel(msg, hdr);
+ rc = -ENOMEM;
+ goto out_unlock;
+ }
+ rc = genlmsg_reply(msg, info);
+ if (rc)
+ GENL_SET_ERR_MSG(info, "failed to send reply");
+ }
+out_unlock:
+ if (rc < 0 && msg)
+ nlmsg_free(msg);
+ mutex_unlock(&console_session.ses_mutex);
+ return rc;
+}
+
+static const struct genl_multicast_group lst_mcast_grps[] = {
+ { .name = "sessions", },
+};
+
+static const struct genl_ops lst_genl_ops[] = {
+ {
+ .cmd = LNET_SELFTEST_CMD_SESSIONS,
+ .dumpit = lst_sessions_show_dump,
+ .doit = lst_sessions_cmd,
+ },
+};
+
+static struct genl_family lst_family = {
+ .name = LNET_SELFTEST_GENL_NAME,
+ .version = LNET_SELFTEST_GENL_VERSION,
+ .maxattr = LN_SCALAR_MAX,
+ .module = THIS_MODULE,
+ .ops = lst_genl_ops,
+ .n_ops = ARRAY_SIZE(lst_genl_ops),
+ .mcgrps = lst_mcast_grps,
+ .n_mcgrps = ARRAY_SIZE(lst_mcast_grps),
+};
+
+int lstcon_init_netlink(void)
+{
+ return genl_register_family(&lst_family);
+}
+
+void lstcon_fini_netlink(void)
+{
+ genl_unregister_family(&lst_family);
+}
@@ -602,7 +602,9 @@ void lstcon_rpc_stat_reply(struct lstcon_rpc_trans *, struct srpc_msg *,
return rc;
msrq = &(*crpc)->crp_rpc->crpc_reqstmsg.msg_body.mksn_reqst;
- msrq->mksn_sid = console_session.ses_id;
+ msrq->mksn_sid.ses_stamp = console_session.ses_id.ses_stamp;
+ msrq->mksn_sid.ses_nid =
+ lnet_nid_to_nid4(&console_session.ses_id.ses_nid);
msrq->mksn_force = console_session.ses_force;
strlcpy(msrq->mksn_name, console_session.ses_name,
sizeof(msrq->mksn_name));
@@ -615,7 +617,9 @@ void lstcon_rpc_stat_reply(struct lstcon_rpc_trans *, struct srpc_msg *,
return rc;
rsrq = &(*crpc)->crp_rpc->crpc_reqstmsg.msg_body.rmsn_reqst;
- rsrq->rmsn_sid = console_session.ses_id;
+ rsrq->rmsn_sid.ses_stamp = console_session.ses_id.ses_stamp;
+ rsrq->rmsn_sid.ses_nid =
+ lnet_nid_to_nid4(&console_session.ses_id.ses_nid);
break;
default:
@@ -638,7 +642,9 @@ void lstcon_rpc_stat_reply(struct lstcon_rpc_trans *, struct srpc_msg *,
drq = &(*crpc)->crp_rpc->crpc_reqstmsg.msg_body.dbg_reqst;
- drq->dbg_sid = console_session.ses_id;
+ drq->dbg_sid.ses_stamp = console_session.ses_id.ses_stamp;
+ drq->dbg_sid.ses_nid =
+ lnet_nid_to_nid4(&console_session.ses_id.ses_nid);
drq->dbg_flags = 0;
return rc;
@@ -658,7 +664,9 @@ void lstcon_rpc_stat_reply(struct lstcon_rpc_trans *, struct srpc_msg *,
brq = &(*crpc)->crp_rpc->crpc_reqstmsg.msg_body.bat_reqst;
- brq->bar_sid = console_session.ses_id;
+ brq->bar_sid.ses_stamp = console_session.ses_id.ses_stamp;
+ brq->bar_sid.ses_nid =
+ lnet_nid_to_nid4(&console_session.ses_id.ses_nid);
brq->bar_bid = tsb->tsb_id;
brq->bar_testidx = tsb->tsb_index;
brq->bar_opc = transop == LST_TRANS_TSBRUN ? SRPC_BATCH_OPC_RUN :
@@ -690,7 +698,9 @@ void lstcon_rpc_stat_reply(struct lstcon_rpc_trans *, struct srpc_msg *,
srq = &(*crpc)->crp_rpc->crpc_reqstmsg.msg_body.stat_reqst;
- srq->str_sid = console_session.ses_id;
+ srq->str_sid.ses_stamp = console_session.ses_id.ses_stamp;
+ srq->str_sid.ses_nid =
+ lnet_nid_to_nid4(&console_session.ses_id.ses_nid);
srq->str_type = 0; /* XXX remove it */
return 0;
@@ -877,7 +887,9 @@ void lstcon_rpc_stat_reply(struct lstcon_rpc_trans *, struct srpc_msg *,
trq->tsr_loop = test->tes_loop;
}
- trq->tsr_sid = console_session.ses_id;
+ trq->tsr_sid.ses_stamp = console_session.ses_id.ses_stamp;
+ trq->tsr_sid.ses_nid =
+ lnet_nid_to_nid4(&console_session.ses_id.ses_nid);
trq->tsr_bid = test->tes_hdr.tsb_id;
trq->tsr_concur = test->tes_concur;
trq->tsr_is_client = (transop == LST_TRANS_TSBCLIADD) ? 1 : 0;
@@ -1259,7 +1271,9 @@ void lstcon_rpc_stat_reply(struct lstcon_rpc_trans *, struct srpc_msg *,
drq = &crpc->crp_rpc->crpc_reqstmsg.msg_body.dbg_reqst;
- drq->dbg_sid = console_session.ses_id;
+ drq->dbg_sid.ses_stamp = console_session.ses_id.ses_stamp;
+ drq->dbg_sid.ses_nid =
+ lnet_nid_to_nid4(&console_session.ses_id.ses_nid);
drq->dbg_flags = 0;
lstcon_rpc_trans_addreq(trans, crpc);
@@ -1679,27 +1679,32 @@ static void lstcon_group_ndlink_release(struct lstcon_group *,
}
int
-lstcon_session_match(struct lst_sid sid)
+lstcon_session_match(struct lst_sid id)
{
- return (console_session.ses_id.ses_nid == sid.ses_nid &&
- console_session.ses_id.ses_stamp == sid.ses_stamp) ? 1 : 0;
+ struct lst_session_id sid;
+
+ sid.ses_stamp = id.ses_stamp;
+ lnet_nid4_to_nid(id.ses_nid, &sid.ses_nid);
+
+ return (nid_same(&console_session.ses_id.ses_nid, &sid.ses_nid) &&
+ console_session.ses_id.ses_stamp == sid.ses_stamp) ? 1 : 0;
}
static void
-lstcon_new_session_id(struct lst_sid *sid)
+lstcon_new_session_id(struct lst_session_id *sid)
{
struct lnet_processid id;
LASSERT(console_session.ses_state == LST_SESSION_NONE);
LNetGetId(1, &id);
- sid->ses_nid = lnet_nid_to_nid4(&id.nid);
+ sid->ses_nid = id.nid;
sid->ses_stamp = div_u64(ktime_get_ns(), NSEC_PER_MSEC);
}
int
lstcon_session_new(char *name, int key, unsigned int feats,
- int timeout, int force, struct lst_sid __user *sid_up)
+ int timeout, int force)
{
int rc = 0;
int i;
@@ -1731,7 +1736,6 @@ static void lstcon_group_ndlink_release(struct lstcon_group *,
lstcon_new_session_id(&console_session.ses_id);
console_session.ses_key = key;
- console_session.ses_state = LST_SESSION_ACTIVE;
console_session.ses_force = !!force;
console_session.ses_features = feats;
console_session.ses_feats_updated = 0;
@@ -1757,52 +1761,12 @@ static void lstcon_group_ndlink_release(struct lstcon_group *,
return rc;
}
- if (!copy_to_user(sid_up, &console_session.ses_id,
- sizeof(struct lst_sid)))
- return rc;
-
- lstcon_session_end();
-
- return -EFAULT;
-}
-
-int
-lstcon_session_info(struct lst_sid __user *sid_up, int __user *key_up,
- unsigned __user *featp,
- struct lstcon_ndlist_ent __user *ndinfo_up,
- char __user *name_up, int len)
-{
- struct lstcon_ndlist_ent *entp;
- struct lstcon_ndlink *ndl;
- int rc = 0;
-
- if (console_session.ses_state != LST_SESSION_ACTIVE)
- return -ESRCH;
-
- entp = kzalloc(sizeof(*entp), GFP_NOFS);
- if (!entp)
- return -ENOMEM;
-
- list_for_each_entry(ndl, &console_session.ses_ndl_list, ndl_link)
- LST_NODE_STATE_COUNTER(ndl->ndl_node, entp);
-
- if (copy_to_user(sid_up, &console_session.ses_id,
- sizeof(*sid_up)) ||
- copy_to_user(key_up, &console_session.ses_key,
- sizeof(*key_up)) ||
- copy_to_user(featp, &console_session.ses_features,
- sizeof(*featp)) ||
- copy_to_user(ndinfo_up, entp, sizeof(*entp)) ||
- copy_to_user(name_up, console_session.ses_name, len))
- rc = -EFAULT;
-
- kfree(entp);
+ console_session.ses_state = LST_SESSION_ACTIVE;
return rc;
}
-int
-lstcon_session_end(void)
+int lstcon_session_end(void)
{
struct lstcon_rpc_trans *trans;
struct lstcon_group *grp;
@@ -1907,9 +1871,10 @@ static void lstcon_group_ndlink_release(struct lstcon_group *,
mutex_lock(&console_session.ses_mutex);
- jrep->join_sid = console_session.ses_id;
+ jrep->join_sid.ses_stamp = console_session.ses_id.ses_stamp;
+ jrep->join_sid.ses_nid = lnet_nid_to_nid4(&console_session.ses_id.ses_nid);
- if (console_session.ses_id.ses_nid == LNET_NID_ANY) {
+ if (LNET_NID_IS_ANY(&console_session.ses_id.ses_nid)) {
jrep->join_status = ESRCH;
goto out;
}
@@ -2041,14 +2006,21 @@ static void lstcon_init_acceptor_service(void)
goto out;
}
+ rc = lstcon_init_netlink();
+ if (rc < 0)
+ goto out;
+
rc = blocking_notifier_chain_register(&libcfs_ioctl_list,
&lstcon_ioctl_handler);
- if (!rc) {
- lstcon_rpc_module_init();
- return 0;
+ if (rc < 0) {
+ lstcon_fini_netlink();
+ goto out;
}
+ lstcon_rpc_module_init();
+ return 0;
+
out:
srpc_shutdown_service(&lstcon_acceptor_service);
srpc_remove_service(&lstcon_acceptor_service);
@@ -2067,6 +2039,7 @@ static void lstcon_init_acceptor_service(void)
blocking_notifier_chain_unregister(&libcfs_ioctl_list,
&lstcon_ioctl_handler);
+ lstcon_fini_netlink();
mutex_lock(&console_session.ses_mutex);
@@ -136,36 +136,34 @@ struct lstcon_test {
#define LST_CONSOLE_TIMEOUT 300 /* default console timeout */
struct lstcon_session {
- struct mutex ses_mutex; /* only 1 thread in session */
- struct lst_sid ses_id; /* global session id */
- int ses_key; /* local session key */
- int ses_state; /* state of session */
- int ses_timeout; /* timeout in seconds */
- time64_t ses_laststamp; /* last operation stamp (secs) */
- unsigned int ses_features; /* tests features of the session */
- unsigned int ses_feats_updated:1; /* features are synced with
- * remote test nodes
- */
- unsigned int ses_force:1; /* force creating */
- unsigned int ses_shutdown:1; /* session is shutting down */
- unsigned int ses_expired:1; /* console is timedout */
- u64 ses_id_cookie; /* batch id cookie */
- char ses_name[LST_NAME_SIZE];/* session name */
- struct lstcon_rpc_trans
- *ses_ping; /* session pinger */
- struct stt_timer ses_ping_timer; /* timer for pinger */
- struct lstcon_trans_stat
- ses_trans_stat; /* transaction stats */
-
- struct list_head ses_trans_list; /* global list of transaction */
- struct list_head ses_grp_list; /* global list of groups */
- struct list_head ses_bat_list; /* global list of batches */
- struct list_head ses_ndl_list; /* global list of nodes */
- struct list_head *ses_ndl_hash; /* hash table of nodes */
-
- spinlock_t ses_rpc_lock; /* serialize */
- atomic_t ses_rpc_counter; /* # of initialized RPCs */
- struct list_head ses_rpc_freelist; /* idle console rpc */
+ struct mutex ses_mutex; /* only 1 thread in session */
+ struct lst_session_id ses_id; /* global session id */
+ u32 ses_key; /* local session key */
+ int ses_state; /* state of session */
+ int ses_timeout; /* timeout in seconds */
+ time64_t ses_laststamp; /* last operation stamp (secs) */
+ unsigned int ses_features; /* tests features of the session */
+ unsigned int ses_feats_updated:1; /* features are synced with
+ * remote test nodes
+ */
+ unsigned int ses_force:1; /* force creating */
+ unsigned int ses_shutdown:1; /* session is shutting down */
+ unsigned int ses_expired:1; /* console is timedout */
+ u64 ses_id_cookie; /* batch id cookie */
+ char ses_name[LST_NAME_SIZE];/* session name */
+ struct lstcon_rpc_trans *ses_ping; /* session pinger */
+ struct stt_timer ses_ping_timer; /* timer for pinger */
+ struct lstcon_trans_stat ses_trans_stat;/* transaction stats */
+
+ struct list_head ses_trans_list; /* global list of transaction */
+ struct list_head ses_grp_list; /* global list of groups */
+ struct list_head ses_bat_list; /* global list of batches */
+ struct list_head ses_ndl_list; /* global list of nodes */
+ struct list_head *ses_ndl_hash; /* hash table of nodes */
+
+ spinlock_t ses_rpc_lock; /* serialize */
+ atomic_t ses_rpc_counter;/* # of initialized RPCs */
+ struct list_head ses_rpc_freelist;/* idle console rpc */
}; /* session descriptor */
extern struct lstcon_session console_session;
@@ -186,14 +184,16 @@ struct lstcon_session {
int lstcon_ioctl_entry(struct notifier_block *nb,
unsigned long cmd, void *vdata);
+
+int lstcon_init_netlink(void);
+void lstcon_fini_netlink(void);
+
int lstcon_console_init(void);
int lstcon_console_fini(void);
+
int lstcon_session_match(struct lst_sid sid);
int lstcon_session_new(char *name, int key, unsigned int version,
- int timeout, int flags, struct lst_sid __user *sid_up);
-int lstcon_session_info(struct lst_sid __user *sid_up, int __user *key,
- unsigned __user *verp, struct lstcon_ndlist_ent __user *entp,
- char __user *name_up, int len);
+ int timeout, int flags);
int lstcon_session_end(void);
int lstcon_session_debug(int timeout, struct list_head __user *result_up);
int lstcon_session_feats_check(unsigned int feats);
@@ -39,7 +39,7 @@
#include "selftest.h"
-struct lst_sid LST_INVALID_SID = { .ses_nid = LNET_NID_ANY, .ses_stamp = -1 };
+struct lst_session_id LST_INVALID_SID = { .ses_nid = LNET_ANY_NID, .ses_stamp = -1};
static int session_timeout = 100;
module_param(session_timeout, int, 0444);
@@ -244,7 +244,7 @@
LASSERT(sn == sfw_data.fw_session);
CWARN("Session expired! sid: %s-%llu, name: %s\n",
- libcfs_nid2str(sn->sn_id.ses_nid),
+ libcfs_nidstr(&sn->sn_id.ses_nid),
sn->sn_id.ses_stamp, &sn->sn_name[0]);
sn->sn_timer_active = 0;
@@ -268,7 +268,8 @@
strlcpy(&sn->sn_name[0], name, sizeof(sn->sn_name));
sn->sn_timer_active = 0;
- sn->sn_id = sid;
+ sn->sn_id.ses_stamp = sid.ses_stamp;
+ lnet_nid4_to_nid(sid.ses_nid, &sn->sn_id.ses_nid);
sn->sn_features = features;
sn->sn_timeout = session_timeout;
sn->sn_started = ktime_get();
@@ -357,6 +358,18 @@
return bat;
}
+static struct lst_sid get_old_sid(struct sfw_session *sn)
+{
+ struct lst_sid sid = { .ses_nid = LNET_NID_ANY, .ses_stamp = -1 };
+
+ if (sn) {
+ sid.ses_stamp = sn->sn_id.ses_stamp;
+ sid.ses_nid = lnet_nid_to_nid4(&sn->sn_id.ses_nid);
+ }
+
+ return sid;
+}
+
static int
sfw_get_stats(struct srpc_stat_reqst *request, struct srpc_stat_reply *reply)
{
@@ -364,7 +377,7 @@
struct sfw_counters *cnt = &reply->str_fw;
struct sfw_batch *bat;
- reply->str_sid = !sn ? LST_INVALID_SID : sn->sn_id;
+ reply->str_sid = get_old_sid(sn);
if (request->str_sid.ses_nid == LNET_NID_ANY) {
reply->str_status = EINVAL;
@@ -407,14 +420,14 @@
int cplen = 0;
if (request->mksn_sid.ses_nid == LNET_NID_ANY) {
- reply->mksn_sid = !sn ? LST_INVALID_SID : sn->sn_id;
+ reply->mksn_sid = get_old_sid(sn);
reply->mksn_status = EINVAL;
return 0;
}
if (sn) {
reply->mksn_status = 0;
- reply->mksn_sid = sn->sn_id;
+ reply->mksn_sid = get_old_sid(sn);
reply->mksn_timeout = sn->sn_timeout;
if (sfw_sid_equal(request->mksn_sid, sn->sn_id)) {
@@ -464,7 +477,7 @@
spin_unlock(&sfw_data.fw_lock);
reply->mksn_status = 0;
- reply->mksn_sid = sn->sn_id;
+ reply->mksn_sid = get_old_sid(sn);
reply->mksn_timeout = sn->sn_timeout;
return 0;
}
@@ -475,7 +488,7 @@
{
struct sfw_session *sn = sfw_data.fw_session;
- reply->rmsn_sid = !sn ? LST_INVALID_SID : sn->sn_id;
+ reply->rmsn_sid = get_old_sid(sn);
if (request->rmsn_sid.ses_nid == LNET_NID_ANY) {
reply->rmsn_status = EINVAL;
@@ -497,7 +510,7 @@
spin_unlock(&sfw_data.fw_lock);
reply->rmsn_status = 0;
- reply->rmsn_sid = LST_INVALID_SID;
+ reply->rmsn_sid = get_old_sid(NULL);
LASSERT(!sfw_data.fw_session);
return 0;
}
@@ -510,12 +523,12 @@
if (!sn) {
reply->dbg_status = ESRCH;
- reply->dbg_sid = LST_INVALID_SID;
+ reply->dbg_sid = get_old_sid(NULL);
return 0;
}
reply->dbg_status = 0;
- reply->dbg_sid = sn->sn_id;
+ reply->dbg_sid = get_old_sid(sn);
reply->dbg_timeout = sn->sn_timeout;
if (strlcpy(reply->dbg_name, &sn->sn_name[0], sizeof(reply->dbg_name))
>= sizeof(reply->dbg_name))
@@ -1119,7 +1132,7 @@
struct sfw_batch *bat;
request = &rpc->srpc_reqstbuf->buf_msg.msg_body.tes_reqst;
- reply->tsr_sid = !sn ? LST_INVALID_SID : sn->sn_id;
+ reply->tsr_sid = get_old_sid(sn);
if (!request->tsr_loop ||
!request->tsr_concur ||
@@ -1187,7 +1200,7 @@
int rc = 0;
struct sfw_batch *bat;
- reply->bar_sid = !sn ? LST_INVALID_SID : sn->sn_id;
+ reply->bar_sid = get_old_sid(sn);
if (!sn || !sfw_sid_equal(request->bar_sid, sn->sn_id)) {
reply->bar_status = ESRCH;
@@ -1266,7 +1279,9 @@
CNETERR("Features of framework RPC don't match features of current session: %x/%x\n",
request->msg_ses_feats, sn->sn_features);
reply->msg_body.reply.status = EPROTO;
- reply->msg_body.reply.sid = sn->sn_id;
+ reply->msg_body.reply.sid.ses_stamp = sn->sn_id.ses_stamp;
+ reply->msg_body.reply.sid.ses_nid =
+ lnet_nid_to_nid4(&sn->sn_id.ses_nid);
goto out;
}
@@ -49,6 +49,39 @@
#define MADE_WITHOUT_COMPROMISE
#endif
+/* enum lnet_selftest_session_attrs - LNet selftest session Netlink
+ * attributes
+ *
+ * @LNET_SELFTEST_SESSION_UNSPEC: unspecified attribute to catch errors
+ * @LNET_SELFTEST_SESSION_PAD: padding for 64-bit attributes, ignore
+ *
+ * @LENT_SELFTEST_SESSION_HDR: Netlink group this data is for
+ * (NLA_NUL_STRING)
+ * @LNET_SELFTEST_SESSION_NAME: name of this session (NLA_STRING)
+ * @LNET_SELFTEST_SESSION_KEY: key used to represent the session
+ * (NLA_U32)
+ * @LNET_SELFTEST_SESSION_TIMESTAMP: timestamp when the session was created
+ * (NLA_S64)
+ * @LNET_SELFTEST_SESSION_NID: NID of the node selftest ran on
+ * (NLA_STRING)
+ * @LNET_SELFTEST_SESSION_NODE_COUNT: Number of nodes in use (NLA_U16)
+ */
+enum lnet_selftest_session_attrs {
+ LNET_SELFTEST_SESSION_UNSPEC = 0,
+ LNET_SELFTEST_SESSION_PAD = LNET_SELFTEST_SESSION_UNSPEC,
+
+ LNET_SELFTEST_SESSION_HDR,
+ LNET_SELFTEST_SESSION_NAME,
+ LNET_SELFTEST_SESSION_KEY,
+ LNET_SELFTEST_SESSION_TIMESTAMP,
+ LNET_SELFTEST_SESSION_NID,
+ LNET_SELFTEST_SESSION_NODE_COUNT,
+
+ __LNET_SELFTEST_SESSION_MAX_PLUS_ONE,
+};
+
+#define LNET_SELFTEST_SESSION_MAX (__LNET_SELFTEST_SESSION_MAX_PLUS_ONE - 1)
+
#define SWI_STATE_NEWBORN 0
#define SWI_STATE_REPLY_SUBMITTED 1
#define SWI_STATE_REPLY_SENT 2
@@ -318,23 +351,40 @@ struct srpc_service {
int (*sv_bulk_ready)(struct srpc_server_rpc *, int);
};
+struct lst_session_id {
+ s64 ses_stamp; /* time stamp in milliseconds */
+ struct lnet_nid ses_nid; /* nid of console node */
+}; /*** session id (large addr) */
+
+extern struct lst_session_id LST_INVALID_SID;
+
struct sfw_session {
- struct list_head sn_list; /* chain on fw_zombie_sessions */
- struct lst_sid sn_id; /* unique identifier */
- unsigned int sn_timeout; /* # seconds' inactivity to expire */
- int sn_timer_active;
- unsigned int sn_features;
- struct stt_timer sn_timer;
- struct list_head sn_batches; /* list of batches */
- char sn_name[LST_NAME_SIZE];
- atomic_t sn_refcount;
- atomic_t sn_brw_errors;
- atomic_t sn_ping_errors;
- ktime_t sn_started;
+ /* chain on fw_zombie_sessions */
+ struct list_head sn_list;
+ struct lst_session_id sn_id; /* unique identifier */
+ /* # seconds' inactivity to expire */
+ unsigned int sn_timeout;
+ int sn_timer_active;
+ unsigned int sn_features;
+ struct stt_timer sn_timer;
+ struct list_head sn_batches; /* list of batches */
+ char sn_name[LST_NAME_SIZE];
+ atomic_t sn_refcount;
+ atomic_t sn_brw_errors;
+ atomic_t sn_ping_errors;
+ ktime_t sn_started;
};
-#define sfw_sid_equal(sid0, sid1) ((sid0).ses_nid == (sid1).ses_nid && \
- (sid0).ses_stamp == (sid1).ses_stamp)
+static inline int sfw_sid_equal(struct lst_sid sid0,
+ struct lst_session_id sid1)
+{
+ struct lnet_nid ses_nid;
+
+ lnet_nid4_to_nid(sid0.ses_nid, &ses_nid);
+
+ return ((sid0.ses_stamp == sid1.ses_stamp) &&
+ nid_same(&ses_nid, &sid1.ses_nid));
+}
struct sfw_batch {
struct list_head bat_list; /* chain on sn_batches */