/*
 * GPL HEADER START
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 only,
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License version 2 for more details (a copy is included
 * 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
 * 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
 * have any questions.
 *
 * GPL HEADER END
 */
/*
 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
 * Use is subject to license terms.
 *
 * Copyright (c) 2011, 2012, Intel Corporation.
 */
/*
 * This file is part of Lustre, http://www.lustre.org/
 * Lustre is a trademark of Sun Microsystems, Inc.
 *
 * lnet/selftest/conctl.c
 *
 * Console framework rpcs
 *
 * Author: Liang Zhen <liang@whamcloud.com>
 */


#include "../../include/linux/libcfs/libcfs.h"
#include "../../include/linux/lnet/lib-lnet.h"
#include "timer.h"
#include "conrpc.h"
#include "console.h"

void lstcon_rpc_stat_reply(lstcon_rpc_trans_t *, srpc_msg_t *,
			   lstcon_node_t *, lstcon_trans_stat_t *);

static void
lstcon_rpc_done(srpc_client_rpc_t *rpc)
{
	lstcon_rpc_t *crpc = (lstcon_rpc_t *)rpc->crpc_priv;

	LASSERT(crpc != NULL && rpc == crpc->crp_rpc);
	LASSERT(crpc->crp_posted && !crpc->crp_finished);

	spin_lock(&rpc->crpc_lock);

	if (crpc->crp_trans == NULL) {
		/* Orphan RPC is not in any transaction,
		 * I'm just a poor body and nobody loves me */
		spin_unlock(&rpc->crpc_lock);

		/* release it */
		lstcon_rpc_put(crpc);
		return;
	}

	/* not an orphan RPC */
	crpc->crp_finished = 1;

	if (crpc->crp_stamp == 0) {
		/* not aborted */
		LASSERT(crpc->crp_status == 0);

		crpc->crp_stamp  = cfs_time_current();
		crpc->crp_status = rpc->crpc_status;
	}

	/* wakeup (transaction)thread if I'm the last RPC in the transaction */
	if (atomic_dec_and_test(&crpc->crp_trans->tas_remaining))
		wake_up(&crpc->crp_trans->tas_waitq);

	spin_unlock(&rpc->crpc_lock);
}

static int
lstcon_rpc_init(lstcon_node_t *nd, int service, unsigned feats,
		int bulk_npg, int bulk_len, int embedded, lstcon_rpc_t *crpc)
{
	crpc->crp_rpc = sfw_create_rpc(nd->nd_id, service,
				       feats, bulk_npg, bulk_len,
				       lstcon_rpc_done, (void *)crpc);
	if (crpc->crp_rpc == NULL)
		return -ENOMEM;

	crpc->crp_trans    = NULL;
	crpc->crp_node     = nd;
	crpc->crp_posted   = 0;
	crpc->crp_finished = 0;
	crpc->crp_unpacked = 0;
	crpc->crp_status   = 0;
	crpc->crp_stamp    = 0;
	crpc->crp_embedded = embedded;
	INIT_LIST_HEAD(&crpc->crp_link);

	atomic_inc(&console_session.ses_rpc_counter);

	return 0;
}

static int
lstcon_rpc_prep(lstcon_node_t *nd, int service, unsigned feats,
		int bulk_npg, int bulk_len, lstcon_rpc_t **crpcpp)
{
	lstcon_rpc_t  *crpc = NULL;
	int	    rc;

	spin_lock(&console_session.ses_rpc_lock);

	if (!list_empty(&console_session.ses_rpc_freelist)) {
		crpc = list_entry(console_session.ses_rpc_freelist.next,
				      lstcon_rpc_t, crp_link);
		list_del_init(&crpc->crp_link);
	}

	spin_unlock(&console_session.ses_rpc_lock);

	if (crpc == NULL) {
		LIBCFS_ALLOC(crpc, sizeof(*crpc));
		if (crpc == NULL)
			return -ENOMEM;
	}

	rc = lstcon_rpc_init(nd, service, feats, bulk_npg, bulk_len, 0, crpc);
	if (rc == 0) {
		*crpcpp = crpc;
		return 0;
	}

	LIBCFS_FREE(crpc, sizeof(*crpc));

	return rc;
}

void
lstcon_rpc_put(lstcon_rpc_t *crpc)
{
	srpc_bulk_t *bulk = &crpc->crp_rpc->crpc_bulk;
	int	  i;

	LASSERT(list_empty(&crpc->crp_link));

	for (i = 0; i < bulk->bk_niov; i++) {
		if (bulk->bk_iovs[i].kiov_page == NULL)
			continue;

		__free_page(bulk->bk_iovs[i].kiov_page);
	}

	srpc_client_rpc_decref(crpc->crp_rpc);

	if (crpc->crp_embedded) {
		/* embedded RPC, don't recycle it */
		memset(crpc, 0, sizeof(*crpc));
		crpc->crp_embedded = 1;

	} else {
		spin_lock(&console_session.ses_rpc_lock);

		list_add(&crpc->crp_link,
			     &console_session.ses_rpc_freelist);

		spin_unlock(&console_session.ses_rpc_lock);
	}

	/* RPC is not alive now */
	atomic_dec(&console_session.ses_rpc_counter);
}

static void
lstcon_rpc_post(lstcon_rpc_t *crpc)
{
	lstcon_rpc_trans_t *trans = crpc->crp_trans;

	LASSERT(trans != NULL);

	atomic_inc(&trans->tas_remaining);
	crpc->crp_posted = 1;

	sfw_post_rpc(crpc->crp_rpc);
}

static char *
lstcon_rpc_trans_name(int transop)
{
	if (transop == LST_TRANS_SESNEW)
		return "SESNEW";

	if (transop == LST_TRANS_SESEND)
		return "SESEND";

	if (transop == LST_TRANS_SESQRY)
		return "SESQRY";

	if (transop == LST_TRANS_SESPING)
		return "SESPING";

	if (transop == LST_TRANS_TSBCLIADD)
		return "TSBCLIADD";

	if (transop == LST_TRANS_TSBSRVADD)
		return "TSBSRVADD";

	if (transop == LST_TRANS_TSBRUN)
		return "TSBRUN";

	if (transop == LST_TRANS_TSBSTOP)
		return "TSBSTOP";

	if (transop == LST_TRANS_TSBCLIQRY)
		return "TSBCLIQRY";

	if (transop == LST_TRANS_TSBSRVQRY)
		return "TSBSRVQRY";

	if (transop == LST_TRANS_STATQRY)
		return "STATQRY";

	return "Unknown";
}

int
lstcon_rpc_trans_prep(struct list_head *translist,
		      int transop, lstcon_rpc_trans_t **transpp)
{
	lstcon_rpc_trans_t *trans;

	if (translist != NULL) {
		list_for_each_entry(trans, translist, tas_link) {
			/* Can't enqueue two private transaction on
			 * the same object */
			if ((trans->tas_opc & transop) == LST_TRANS_PRIVATE)
				return -EPERM;
		}
	}

	/* create a trans group */
	LIBCFS_ALLOC(trans, sizeof(*trans));
	if (trans == NULL)
		return -ENOMEM;

	trans->tas_opc = transop;

	if (translist == NULL)
		INIT_LIST_HEAD(&trans->tas_olink);
	else
		list_add_tail(&trans->tas_olink, translist);

	list_add_tail(&trans->tas_link, &console_session.ses_trans_list);

	INIT_LIST_HEAD(&trans->tas_rpcs_list);
	atomic_set(&trans->tas_remaining, 0);
	init_waitqueue_head(&trans->tas_waitq);

	spin_lock(&console_session.ses_rpc_lock);
	trans->tas_features = console_session.ses_features;
	spin_unlock(&console_session.ses_rpc_lock);

	*transpp = trans;
	return 0;
}

void
lstcon_rpc_trans_addreq(lstcon_rpc_trans_t *trans, lstcon_rpc_t *crpc)
{
	list_add_tail(&crpc->crp_link, &trans->tas_rpcs_list);
	crpc->crp_trans = trans;
}

void
lstcon_rpc_trans_abort(lstcon_rpc_trans_t *trans, int error)
{
	srpc_client_rpc_t *rpc;
	lstcon_rpc_t      *crpc;
	lstcon_node_t     *nd;

	list_for_each_entry(crpc, &trans->tas_rpcs_list, crp_link) {
		rpc = crpc->crp_rpc;

		spin_lock(&rpc->crpc_lock);

		if (!crpc->crp_posted || /* not posted */
		    crpc->crp_stamp != 0) { /* rpc done or aborted already */
			if (crpc->crp_stamp == 0) {
				crpc->crp_stamp = cfs_time_current();
				crpc->crp_status = -EINTR;
			}
			spin_unlock(&rpc->crpc_lock);
			continue;
		}

		crpc->crp_stamp  = cfs_time_current();
		crpc->crp_status = error;

		spin_unlock(&rpc->crpc_lock);

		sfw_abort_rpc(rpc);

		if (error != ETIMEDOUT)
			continue;

		nd = crpc->crp_node;
		if (cfs_time_after(nd->nd_stamp, crpc->crp_stamp))
			continue;

		nd->nd_stamp = crpc->crp_stamp;
		nd->nd_state = LST_NODE_DOWN;
	}
}

static int
lstcon_rpc_trans_check(lstcon_rpc_trans_t *trans)
{
	if (console_session.ses_shutdown &&
	    !list_empty(&trans->tas_olink)) /* Not an end session RPC */
		return 1;

	return (atomic_read(&trans->tas_remaining) == 0) ? 1 : 0;
}

int
lstcon_rpc_trans_postwait(lstcon_rpc_trans_t *trans, int timeout)
{
	lstcon_rpc_t  *crpc;
	int	    rc;

	if (list_empty(&trans->tas_rpcs_list))
		return 0;

	if (timeout < LST_TRANS_MIN_TIMEOUT)
		timeout = LST_TRANS_MIN_TIMEOUT;

	CDEBUG(D_NET, "Transaction %s started\n",
	       lstcon_rpc_trans_name(trans->tas_opc));

	/* post all requests */
	list_for_each_entry(crpc, &trans->tas_rpcs_list, crp_link) {
		LASSERT(!crpc->crp_posted);

		lstcon_rpc_post(crpc);
	}

	mutex_unlock(&console_session.ses_mutex);

	rc = wait_event_interruptible_timeout(trans->tas_waitq,
					      lstcon_rpc_trans_check(trans),
					      cfs_time_seconds(timeout));
	rc = (rc > 0) ? 0 : ((rc < 0) ? -EINTR : -ETIMEDOUT);

	mutex_lock(&console_session.ses_mutex);

	if (console_session.ses_shutdown)
		rc = -ESHUTDOWN;

	if (rc != 0 || atomic_read(&trans->tas_remaining) != 0) {
		/* treat short timeout as canceled */
		if (rc == -ETIMEDOUT && timeout < LST_TRANS_MIN_TIMEOUT * 2)
			rc = -EINTR;

		lstcon_rpc_trans_abort(trans, rc);
	}

	CDEBUG(D_NET, "Transaction %s stopped: %d\n",
	       lstcon_rpc_trans_name(trans->tas_opc), rc);

	lstcon_rpc_trans_stat(trans, lstcon_trans_stat());

	return rc;
}

static int
lstcon_rpc_get_reply(lstcon_rpc_t *crpc, srpc_msg_t **msgpp)
{
	lstcon_node_t	*nd  = crpc->crp_node;
	srpc_client_rpc_t    *rpc = crpc->crp_rpc;
	srpc_generic_reply_t *rep;

	LASSERT(nd != NULL && rpc != NULL);
	LASSERT(crpc->crp_stamp != 0);

	if (crpc->crp_status != 0) {
		*msgpp = NULL;
		return crpc->crp_status;
	}

	*msgpp = &rpc->crpc_replymsg;
	if (!crpc->crp_unpacked) {
		sfw_unpack_message(*msgpp);
		crpc->crp_unpacked = 1;
	}

	if (cfs_time_after(nd->nd_stamp, crpc->crp_stamp))
		return 0;

	nd->nd_stamp = crpc->crp_stamp;
	rep = &(*msgpp)->msg_body.reply;

	if (rep->sid.ses_nid == LNET_NID_ANY)
		nd->nd_state = LST_NODE_UNKNOWN;
	else if (lstcon_session_match(rep->sid))
		nd->nd_state = LST_NODE_ACTIVE;
	else
		nd->nd_state = LST_NODE_BUSY;

	return 0;
}

void
lstcon_rpc_trans_stat(lstcon_rpc_trans_t *trans, lstcon_trans_stat_t *stat)
{
	lstcon_rpc_t      *crpc;
	srpc_msg_t	*rep;
	int		error;

	LASSERT(stat != NULL);

	memset(stat, 0, sizeof(*stat));

	list_for_each_entry(crpc, &trans->tas_rpcs_list, crp_link) {
		lstcon_rpc_stat_total(stat, 1);

		LASSERT(crpc->crp_stamp != 0);

		error = lstcon_rpc_get_reply(crpc, &rep);
		if (error != 0) {
			lstcon_rpc_stat_failure(stat, 1);
			if (stat->trs_rpc_errno == 0)
				stat->trs_rpc_errno = -error;

			continue;
		}

		lstcon_rpc_stat_success(stat, 1);

		lstcon_rpc_stat_reply(trans, rep, crpc->crp_node, stat);
	}

	if (trans->tas_opc == LST_TRANS_SESNEW && stat->trs_fwk_errno == 0) {
		stat->trs_fwk_errno =
		      lstcon_session_feats_check(trans->tas_features);
	}

	CDEBUG(D_NET, "transaction %s : success %d, failure %d, total %d, RPC error(%d), Framework error(%d)\n",
	       lstcon_rpc_trans_name(trans->tas_opc),
	       lstcon_rpc_stat_success(stat, 0),
	       lstcon_rpc_stat_failure(stat, 0),
	       lstcon_rpc_stat_total(stat, 0),
	       stat->trs_rpc_errno, stat->trs_fwk_errno);

	return;
}

int
lstcon_rpc_trans_interpreter(lstcon_rpc_trans_t *trans,
			     struct list_head *head_up,
			     lstcon_rpc_readent_func_t readent)
{
	struct list_head	    tmp;
	struct list_head	   *next;
	lstcon_rpc_ent_t     *ent;
	srpc_generic_reply_t *rep;
	lstcon_rpc_t	 *crpc;
	srpc_msg_t	   *msg;
	lstcon_node_t	*nd;
	long	dur;
	struct timeval	tv;
	int		   error;

	LASSERT(head_up != NULL);

	next = head_up;

	list_for_each_entry(crpc, &trans->tas_rpcs_list, crp_link) {
		if (copy_from_user(&tmp, next,
				       sizeof(struct list_head)))
			return -EFAULT;

		if (tmp.next == head_up)
			return 0;

		next = tmp.next;

		ent = list_entry(next, lstcon_rpc_ent_t, rpe_link);

		LASSERT(crpc->crp_stamp != 0);

		error = lstcon_rpc_get_reply(crpc, &msg);

		nd = crpc->crp_node;

		dur = (long)cfs_time_sub(crpc->crp_stamp,
		      (unsigned long)console_session.ses_id.ses_stamp);
		cfs_duration_usec(dur, &tv);

		if (copy_to_user(&ent->rpe_peer,
				     &nd->nd_id, sizeof(lnet_process_id_t)) ||
		    copy_to_user(&ent->rpe_stamp, &tv, sizeof(tv)) ||
		    copy_to_user(&ent->rpe_state,
				     &nd->nd_state, sizeof(nd->nd_state)) ||
		    copy_to_user(&ent->rpe_rpc_errno, &error,
				     sizeof(error)))
			return -EFAULT;

		if (error != 0)
			continue;

		/* RPC is done */
		rep = (srpc_generic_reply_t *)&msg->msg_body.reply;

		if (copy_to_user(&ent->rpe_sid,
				     &rep->sid, sizeof(lst_sid_t)) ||
		    copy_to_user(&ent->rpe_fwk_errno,
				     &rep->status, sizeof(rep->status)))
			return -EFAULT;

		if (readent == NULL)
			continue;

		error = readent(trans->tas_opc, msg, ent);

		if (error != 0)
			return error;
	}

	return 0;
}

void
lstcon_rpc_trans_destroy(lstcon_rpc_trans_t *trans)
{
	srpc_client_rpc_t *rpc;
	lstcon_rpc_t      *crpc;
	lstcon_rpc_t      *tmp;
	int		count = 0;

	list_for_each_entry_safe(crpc, tmp, &trans->tas_rpcs_list,
				 crp_link) {
		rpc = crpc->crp_rpc;

		spin_lock(&rpc->crpc_lock);

		/* free it if not posted or finished already */
		if (!crpc->crp_posted || crpc->crp_finished) {
			spin_unlock(&rpc->crpc_lock);

			list_del_init(&crpc->crp_link);
			lstcon_rpc_put(crpc);

			continue;
		}

		/* rpcs can be still not callbacked (even LNetMDUnlink is called)
		 * because huge timeout for inaccessible network, don't make
		 * user wait for them, just abandon them, they will be recycled
		 * in callback */

		LASSERT(crpc->crp_status != 0);

		crpc->crp_node  = NULL;
		crpc->crp_trans = NULL;
		list_del_init(&crpc->crp_link);
		count++;

		spin_unlock(&rpc->crpc_lock);

		atomic_dec(&trans->tas_remaining);
	}

	LASSERT(atomic_read(&trans->tas_remaining) == 0);

	list_del(&trans->tas_link);
	if (!list_empty(&trans->tas_olink))
		list_del(&trans->tas_olink);

	CDEBUG(D_NET, "Transaction %s destroyed with %d pending RPCs\n",
	       lstcon_rpc_trans_name(trans->tas_opc), count);

	LIBCFS_FREE(trans, sizeof(*trans));

	return;
}

int
lstcon_sesrpc_prep(lstcon_node_t *nd, int transop,
		   unsigned feats, lstcon_rpc_t **crpc)
{
	srpc_mksn_reqst_t *msrq;
	srpc_rmsn_reqst_t *rsrq;
	int		rc;

	switch (transop) {
	case LST_TRANS_SESNEW:
		rc = lstcon_rpc_prep(nd, SRPC_SERVICE_MAKE_SESSION,
				     feats, 0, 0, crpc);
		if (rc != 0)
			return rc;

		msrq = &(*crpc)->crp_rpc->crpc_reqstmsg.msg_body.mksn_reqst;
		msrq->mksn_sid     = console_session.ses_id;
		msrq->mksn_force   = console_session.ses_force;
		strncpy(msrq->mksn_name, console_session.ses_name,
			strlen(console_session.ses_name));
		break;

	case LST_TRANS_SESEND:
		rc = lstcon_rpc_prep(nd, SRPC_SERVICE_REMOVE_SESSION,
				     feats, 0, 0, crpc);
		if (rc != 0)
			return rc;

		rsrq = &(*crpc)->crp_rpc->crpc_reqstmsg.msg_body.rmsn_reqst;
		rsrq->rmsn_sid = console_session.ses_id;
		break;

	default:
		LBUG();
	}

	return 0;
}

int
lstcon_dbgrpc_prep(lstcon_node_t *nd, unsigned feats, lstcon_rpc_t **crpc)
{
	srpc_debug_reqst_t *drq;
	int		    rc;

	rc = lstcon_rpc_prep(nd, SRPC_SERVICE_DEBUG, feats, 0, 0, crpc);
	if (rc != 0)
		return rc;

	drq = &(*crpc)->crp_rpc->crpc_reqstmsg.msg_body.dbg_reqst;

	drq->dbg_sid   = console_session.ses_id;
	drq->dbg_flags = 0;

	return rc;
}

int
lstcon_batrpc_prep(lstcon_node_t *nd, int transop, unsigned feats,
		   lstcon_tsb_hdr_t *tsb, lstcon_rpc_t **crpc)
{
	lstcon_batch_t	   *batch;
	srpc_batch_reqst_t *brq;
	int		    rc;

	rc = lstcon_rpc_prep(nd, SRPC_SERVICE_BATCH, feats, 0, 0, crpc);
	if (rc != 0)
		return rc;

	brq = &(*crpc)->crp_rpc->crpc_reqstmsg.msg_body.bat_reqst;

	brq->bar_sid     = console_session.ses_id;
	brq->bar_bid     = tsb->tsb_id;
	brq->bar_testidx = tsb->tsb_index;
	brq->bar_opc     = transop == LST_TRANS_TSBRUN ? SRPC_BATCH_OPC_RUN :
			   (transop == LST_TRANS_TSBSTOP ? SRPC_BATCH_OPC_STOP :
			    SRPC_BATCH_OPC_QUERY);

	if (transop != LST_TRANS_TSBRUN &&
	    transop != LST_TRANS_TSBSTOP)
		return 0;

	LASSERT(tsb->tsb_index == 0);

	batch = (lstcon_batch_t *)tsb;
	brq->bar_arg = batch->bat_arg;

	return 0;
}

int
lstcon_statrpc_prep(lstcon_node_t *nd, unsigned feats, lstcon_rpc_t **crpc)
{
	srpc_stat_reqst_t *srq;
	int		   rc;

	rc = lstcon_rpc_prep(nd, SRPC_SERVICE_QUERY_STAT, feats, 0, 0, crpc);
	if (rc != 0)
		return rc;

	srq = &(*crpc)->crp_rpc->crpc_reqstmsg.msg_body.stat_reqst;

	srq->str_sid  = console_session.ses_id;
	srq->str_type = 0; /* XXX remove it */

	return 0;
}

static lnet_process_id_packed_t *
lstcon_next_id(int idx, int nkiov, lnet_kiov_t *kiov)
{
	lnet_process_id_packed_t *pid;
	int		       i;

	i = idx / SFW_ID_PER_PAGE;

	LASSERT(i < nkiov);

	pid = (lnet_process_id_packed_t *)page_address(kiov[i].kiov_page);

	return &pid[idx % SFW_ID_PER_PAGE];
}

static int
lstcon_dstnodes_prep(lstcon_group_t *grp, int idx,
		     int dist, int span, int nkiov, lnet_kiov_t *kiov)
{
	lnet_process_id_packed_t *pid;
	lstcon_ndlink_t	  *ndl;
	lstcon_node_t	    *nd;
	int		       start;
	int		       end;
	int		       i = 0;

	LASSERT(dist >= 1);
	LASSERT(span >= 1);
	LASSERT(grp->grp_nnode >= 1);

	if (span > grp->grp_nnode)
		return -EINVAL;

	start = ((idx / dist) * span) % grp->grp_nnode;
	end   = ((idx / dist) * span + span - 1) % grp->grp_nnode;

	list_for_each_entry(ndl, &grp->grp_ndl_list, ndl_link) {
		nd = ndl->ndl_node;
		if (i < start) {
			i++;
			continue;
		}

		if (i > (end >= start ? end : grp->grp_nnode))
			break;

		pid = lstcon_next_id((i - start), nkiov, kiov);
		pid->nid = nd->nd_id.nid;
		pid->pid = nd->nd_id.pid;
		i++;
	}

	if (start <= end) /* done */
		return 0;

	list_for_each_entry(ndl, &grp->grp_ndl_list, ndl_link) {
		if (i > grp->grp_nnode + end)
			break;

		nd = ndl->ndl_node;
		pid = lstcon_next_id((i - start), nkiov, kiov);
		pid->nid = nd->nd_id.nid;
		pid->pid = nd->nd_id.pid;
		i++;
	}

	return 0;
}

static int
lstcon_pingrpc_prep(lst_test_ping_param_t *param, srpc_test_reqst_t *req)
{
	test_ping_req_t *prq = &req->tsr_u.ping;

	prq->png_size   = param->png_size;
	prq->png_flags  = param->png_flags;
	/* TODO dest */
	return 0;
}

static int
lstcon_bulkrpc_v0_prep(lst_test_bulk_param_t *param, srpc_test_reqst_t *req)
{
	test_bulk_req_t *brq = &req->tsr_u.bulk_v0;

	brq->blk_opc    = param->blk_opc;
	brq->blk_npg    = (param->blk_size + PAGE_CACHE_SIZE - 1) / PAGE_CACHE_SIZE;
	brq->blk_flags  = param->blk_flags;

	return 0;
}

static int
lstcon_bulkrpc_v1_prep(lst_test_bulk_param_t *param, srpc_test_reqst_t *req)
{
	test_bulk_req_v1_t *brq = &req->tsr_u.bulk_v1;

	brq->blk_opc	= param->blk_opc;
	brq->blk_flags	= param->blk_flags;
	brq->blk_len	= param->blk_size;
	brq->blk_offset	= 0; /* reserved */

	return 0;
}

int
lstcon_testrpc_prep(lstcon_node_t *nd, int transop, unsigned feats,
		    lstcon_test_t *test, lstcon_rpc_t **crpc)
{
	lstcon_group_t    *sgrp = test->tes_src_grp;
	lstcon_group_t    *dgrp = test->tes_dst_grp;
	srpc_test_reqst_t *trq;
	srpc_bulk_t       *bulk;
	int		i;
	int		   npg = 0;
	int		   nob = 0;
	int		   rc  = 0;

	if (transop == LST_TRANS_TSBCLIADD) {
		npg = sfw_id_pages(test->tes_span);
		nob = (feats & LST_FEAT_BULK_LEN) == 0 ?
		      npg * PAGE_CACHE_SIZE :
		      sizeof(lnet_process_id_packed_t) * test->tes_span;
	}

	rc = lstcon_rpc_prep(nd, SRPC_SERVICE_TEST, feats, npg, nob, crpc);
	if (rc != 0)
		return rc;

	trq  = &(*crpc)->crp_rpc->crpc_reqstmsg.msg_body.tes_reqst;

	if (transop == LST_TRANS_TSBSRVADD) {
		int ndist = (sgrp->grp_nnode + test->tes_dist - 1) / test->tes_dist;
		int nspan = (dgrp->grp_nnode + test->tes_span - 1) / test->tes_span;
		int nmax = (ndist + nspan - 1) / nspan;

		trq->tsr_ndest = 0;
		trq->tsr_loop  = nmax * test->tes_dist * test->tes_concur;

	} else {
		bulk = &(*crpc)->crp_rpc->crpc_bulk;

		for (i = 0; i < npg; i++) {
			int	len;

			LASSERT(nob > 0);

			len = (feats & LST_FEAT_BULK_LEN) == 0 ?
			      PAGE_CACHE_SIZE : min_t(int, nob, PAGE_CACHE_SIZE);
			nob -= len;

			bulk->bk_iovs[i].kiov_offset = 0;
			bulk->bk_iovs[i].kiov_len    = len;
			bulk->bk_iovs[i].kiov_page   =
				alloc_page(GFP_IOFS);

			if (bulk->bk_iovs[i].kiov_page == NULL) {
				lstcon_rpc_put(*crpc);
				return -ENOMEM;
			}
		}

		bulk->bk_sink = 0;

		LASSERT(transop == LST_TRANS_TSBCLIADD);

		rc = lstcon_dstnodes_prep(test->tes_dst_grp,
					  test->tes_cliidx++,
					  test->tes_dist,
					  test->tes_span,
					  npg, &bulk->bk_iovs[0]);
		if (rc != 0) {
			lstcon_rpc_put(*crpc);
			return rc;
		}

		trq->tsr_ndest = test->tes_span;
		trq->tsr_loop  = test->tes_loop;
	}

	trq->tsr_sid	= console_session.ses_id;
	trq->tsr_bid	= test->tes_hdr.tsb_id;
	trq->tsr_concur     = test->tes_concur;
	trq->tsr_is_client  = (transop == LST_TRANS_TSBCLIADD) ? 1 : 0;
	trq->tsr_stop_onerr = !!test->tes_stop_onerr;

	switch (test->tes_type) {
	case LST_TEST_PING:
		trq->tsr_service = SRPC_SERVICE_PING;
		rc = lstcon_pingrpc_prep((lst_test_ping_param_t *)
					 &test->tes_param[0], trq);
		break;

	case LST_TEST_BULK:
		trq->tsr_service = SRPC_SERVICE_BRW;
		if ((feats & LST_FEAT_BULK_LEN) == 0) {
			rc = lstcon_bulkrpc_v0_prep((lst_test_bulk_param_t *)
						    &test->tes_param[0], trq);
		} else {
			rc = lstcon_bulkrpc_v1_prep((lst_test_bulk_param_t *)
						    &test->tes_param[0], trq);
		}

		break;
	default:
		LBUG();
		break;
	}

	return rc;
}

static int
lstcon_sesnew_stat_reply(lstcon_rpc_trans_t *trans,
			 lstcon_node_t *nd, srpc_msg_t *reply)
{
	srpc_mksn_reply_t *mksn_rep = &reply->msg_body.mksn_reply;
	int		   status   = mksn_rep->mksn_status;

	if (status == 0 &&
	    (reply->msg_ses_feats & ~LST_FEATS_MASK) != 0) {
		mksn_rep->mksn_status = EPROTO;
		status = EPROTO;
	}

	if (status == EPROTO) {
		CNETERR("session protocol error from %s: %u\n",
			libcfs_nid2str(nd->nd_id.nid),
			reply->msg_ses_feats);
	}

	if (status != 0)
		return status;

	if (!trans->tas_feats_updated) {
		trans->tas_feats_updated = 1;
		trans->tas_features = reply->msg_ses_feats;
	}

	if (reply->msg_ses_feats != trans->tas_features) {
		CNETERR("Framework features %x from %s is different with features on this transaction: %x\n",
			 reply->msg_ses_feats, libcfs_nid2str(nd->nd_id.nid),
			 trans->tas_features);
		status = mksn_rep->mksn_status = EPROTO;
	}

	if (status == 0) {
		/* session timeout on remote node */
		nd->nd_timeout = mksn_rep->mksn_timeout;
	}

	return status;
}

void
lstcon_rpc_stat_reply(lstcon_rpc_trans_t *trans, srpc_msg_t *msg,
		      lstcon_node_t *nd, lstcon_trans_stat_t *stat)
{
	srpc_rmsn_reply_t  *rmsn_rep;
	srpc_debug_reply_t *dbg_rep;
	srpc_batch_reply_t *bat_rep;
	srpc_test_reply_t  *test_rep;
	srpc_stat_reply_t  *stat_rep;
	int		 rc = 0;

	switch (trans->tas_opc) {
	case LST_TRANS_SESNEW:
		rc = lstcon_sesnew_stat_reply(trans, nd, msg);
		if (rc == 0) {
			lstcon_sesop_stat_success(stat, 1);
			return;
		}

		lstcon_sesop_stat_failure(stat, 1);
		break;

	case LST_TRANS_SESEND:
		rmsn_rep = &msg->msg_body.rmsn_reply;
		/* ESRCH is not an error for end session */
		if (rmsn_rep->rmsn_status == 0 ||
		    rmsn_rep->rmsn_status == ESRCH) {
			lstcon_sesop_stat_success(stat, 1);
			return;
		}

		lstcon_sesop_stat_failure(stat, 1);
		rc = rmsn_rep->rmsn_status;
		break;

	case LST_TRANS_SESQRY:
	case LST_TRANS_SESPING:
		dbg_rep = &msg->msg_body.dbg_reply;

		if (dbg_rep->dbg_status == ESRCH) {
			lstcon_sesqry_stat_unknown(stat, 1);
			return;
		}

		if (lstcon_session_match(dbg_rep->dbg_sid))
			lstcon_sesqry_stat_active(stat, 1);
		else
			lstcon_sesqry_stat_busy(stat, 1);
		return;

	case LST_TRANS_TSBRUN:
	case LST_TRANS_TSBSTOP:
		bat_rep = &msg->msg_body.bat_reply;

		if (bat_rep->bar_status == 0) {
			lstcon_tsbop_stat_success(stat, 1);
			return;
		}

		if (bat_rep->bar_status == EPERM &&
		    trans->tas_opc == LST_TRANS_TSBSTOP) {
			lstcon_tsbop_stat_success(stat, 1);
			return;
		}

		lstcon_tsbop_stat_failure(stat, 1);
		rc = bat_rep->bar_status;
		break;

	case LST_TRANS_TSBCLIQRY:
	case LST_TRANS_TSBSRVQRY:
		bat_rep = &msg->msg_body.bat_reply;

		if (bat_rep->bar_active != 0)
			lstcon_tsbqry_stat_run(stat, 1);
		else
			lstcon_tsbqry_stat_idle(stat, 1);

		if (bat_rep->bar_status == 0)
			return;

		lstcon_tsbqry_stat_failure(stat, 1);
		rc = bat_rep->bar_status;
		break;

	case LST_TRANS_TSBCLIADD:
	case LST_TRANS_TSBSRVADD:
		test_rep = &msg->msg_body.tes_reply;

		if (test_rep->tsr_status == 0) {
			lstcon_tsbop_stat_success(stat, 1);
			return;
		}

		lstcon_tsbop_stat_failure(stat, 1);
		rc = test_rep->tsr_status;
		break;

	case LST_TRANS_STATQRY:
		stat_rep = &msg->msg_body.stat_reply;

		if (stat_rep->str_status == 0) {
			lstcon_statqry_stat_success(stat, 1);
			return;
		}

		lstcon_statqry_stat_failure(stat, 1);
		rc = stat_rep->str_status;
		break;

	default:
		LBUG();
	}

	if (stat->trs_fwk_errno == 0)
		stat->trs_fwk_errno = rc;

	return;
}

int
lstcon_rpc_trans_ndlist(struct list_head *ndlist,
			struct list_head *translist, int transop,
			void *arg, lstcon_rpc_cond_func_t condition,
			lstcon_rpc_trans_t **transpp)
{
	lstcon_rpc_trans_t *trans;
	lstcon_ndlink_t    *ndl;
	lstcon_node_t      *nd;
	lstcon_rpc_t       *rpc;
	unsigned	    feats;
	int		 rc;

	/* Creating session RPG for list of nodes */

	rc = lstcon_rpc_trans_prep(translist, transop, &trans);
	if (rc != 0) {
		CERROR("Can't create transaction %d: %d\n", transop, rc);
		return rc;
	}

	feats = trans->tas_features;
	list_for_each_entry(ndl, ndlist, ndl_link) {
		rc = condition == NULL ? 1 :
		     condition(transop, ndl->ndl_node, arg);

		if (rc == 0)
			continue;

		if (rc < 0) {
			CDEBUG(D_NET, "Condition error while creating RPC for transaction %d: %d\n",
					transop, rc);
			break;
		}

		nd = ndl->ndl_node;

		switch (transop) {
		case LST_TRANS_SESNEW:
		case LST_TRANS_SESEND:
			rc = lstcon_sesrpc_prep(nd, transop, feats, &rpc);
			break;
		case LST_TRANS_SESQRY:
		case LST_TRANS_SESPING:
			rc = lstcon_dbgrpc_prep(nd, feats, &rpc);
			break;
		case LST_TRANS_TSBCLIADD:
		case LST_TRANS_TSBSRVADD:
			rc = lstcon_testrpc_prep(nd, transop, feats,
						 (lstcon_test_t *)arg, &rpc);
			break;
		case LST_TRANS_TSBRUN:
		case LST_TRANS_TSBSTOP:
		case LST_TRANS_TSBCLIQRY:
		case LST_TRANS_TSBSRVQRY:
			rc = lstcon_batrpc_prep(nd, transop, feats,
						(lstcon_tsb_hdr_t *)arg, &rpc);
			break;
		case LST_TRANS_STATQRY:
			rc = lstcon_statrpc_prep(nd, feats, &rpc);
			break;
		default:
			rc = -EINVAL;
			break;
		}

		if (rc != 0) {
			CERROR("Failed to create RPC for transaction %s: %d\n",
			       lstcon_rpc_trans_name(transop), rc);
			break;
		}

		lstcon_rpc_trans_addreq(trans, rpc);
	}

	if (rc == 0) {
		*transpp = trans;
		return 0;
	}

	lstcon_rpc_trans_destroy(trans);

	return rc;
}

static void
lstcon_rpc_pinger(void *arg)
{
	stt_timer_t	*ptimer = (stt_timer_t *)arg;
	lstcon_rpc_trans_t *trans;
	lstcon_rpc_t       *crpc;
	srpc_msg_t	 *rep;
	srpc_debug_reqst_t *drq;
	lstcon_ndlink_t    *ndl;
	lstcon_node_t      *nd;
	time_t	      intv;
	int		 count = 0;
	int		 rc;

	/* RPC pinger is a special case of transaction,
	 * it's called by timer at 8 seconds interval.
	 */
	mutex_lock(&console_session.ses_mutex);

	if (console_session.ses_shutdown || console_session.ses_expired) {
		mutex_unlock(&console_session.ses_mutex);
		return;
	}

	if (!console_session.ses_expired &&
	    get_seconds() - console_session.ses_laststamp >
	    (time_t)console_session.ses_timeout)
		console_session.ses_expired = 1;

	trans = console_session.ses_ping;

	LASSERT(trans != NULL);

	list_for_each_entry(ndl, &console_session.ses_ndl_list, ndl_link) {
		nd = ndl->ndl_node;

		if (console_session.ses_expired) {
			/* idle console, end session on all nodes */
			if (nd->nd_state != LST_NODE_ACTIVE)
				continue;

			rc = lstcon_sesrpc_prep(nd, LST_TRANS_SESEND,
						trans->tas_features, &crpc);
			if (rc != 0) {
				CERROR("Out of memory\n");
				break;
			}

			lstcon_rpc_trans_addreq(trans, crpc);
			lstcon_rpc_post(crpc);

			continue;
		}

		crpc = &nd->nd_ping;

		if (crpc->crp_rpc != NULL) {
			LASSERT(crpc->crp_trans == trans);
			LASSERT(!list_empty(&crpc->crp_link));

			spin_lock(&crpc->crp_rpc->crpc_lock);

			LASSERT(crpc->crp_posted);

			if (!crpc->crp_finished) {
				/* in flight */
				spin_unlock(&crpc->crp_rpc->crpc_lock);
				continue;
			}

			spin_unlock(&crpc->crp_rpc->crpc_lock);

			lstcon_rpc_get_reply(crpc, &rep);

			list_del_init(&crpc->crp_link);

			lstcon_rpc_put(crpc);
		}

		if (nd->nd_state != LST_NODE_ACTIVE)
			continue;

		intv = cfs_duration_sec(cfs_time_sub(cfs_time_current(),
						     nd->nd_stamp));
		if (intv < (time_t)nd->nd_timeout / 2)
			continue;

		rc = lstcon_rpc_init(nd, SRPC_SERVICE_DEBUG,
				     trans->tas_features, 0, 0, 1, crpc);
		if (rc != 0) {
			CERROR("Out of memory\n");
			break;
		}

		drq = &crpc->crp_rpc->crpc_reqstmsg.msg_body.dbg_reqst;

		drq->dbg_sid   = console_session.ses_id;
		drq->dbg_flags = 0;

		lstcon_rpc_trans_addreq(trans, crpc);
		lstcon_rpc_post(crpc);

		count++;
	}

	if (console_session.ses_expired) {
		mutex_unlock(&console_session.ses_mutex);
		return;
	}

	CDEBUG(D_NET, "Ping %d nodes in session\n", count);

	ptimer->stt_expires = (unsigned long)(get_seconds() + LST_PING_INTERVAL);
	stt_add_timer(ptimer);

	mutex_unlock(&console_session.ses_mutex);
}

int
lstcon_rpc_pinger_start(void)
{
	stt_timer_t    *ptimer;
	int	     rc;

	LASSERT(list_empty(&console_session.ses_rpc_freelist));
	LASSERT(atomic_read(&console_session.ses_rpc_counter) == 0);

	rc = lstcon_rpc_trans_prep(NULL, LST_TRANS_SESPING,
				   &console_session.ses_ping);
	if (rc != 0) {
		CERROR("Failed to create console pinger\n");
		return rc;
	}

	ptimer = &console_session.ses_ping_timer;
	ptimer->stt_expires = (unsigned long)(get_seconds() + LST_PING_INTERVAL);

	stt_add_timer(ptimer);

	return 0;
}

void
lstcon_rpc_pinger_stop(void)
{
	LASSERT(console_session.ses_shutdown);

	stt_del_timer(&console_session.ses_ping_timer);

	lstcon_rpc_trans_abort(console_session.ses_ping, -ESHUTDOWN);
	lstcon_rpc_trans_stat(console_session.ses_ping, lstcon_trans_stat());
	lstcon_rpc_trans_destroy(console_session.ses_ping);

	memset(lstcon_trans_stat(), 0, sizeof(lstcon_trans_stat_t));

	console_session.ses_ping = NULL;
}

void
lstcon_rpc_cleanup_wait(void)
{
	lstcon_rpc_trans_t *trans;
	lstcon_rpc_t       *crpc;
	struct list_head	 *pacer;
	struct list_head	  zlist;

	/* Called with hold of global mutex */

	LASSERT(console_session.ses_shutdown);

	while (!list_empty(&console_session.ses_trans_list)) {
		list_for_each(pacer, &console_session.ses_trans_list) {
			trans = list_entry(pacer, lstcon_rpc_trans_t,
					       tas_link);

			CDEBUG(D_NET, "Session closed, wakeup transaction %s\n",
			       lstcon_rpc_trans_name(trans->tas_opc));

			wake_up(&trans->tas_waitq);
		}

		mutex_unlock(&console_session.ses_mutex);

		CWARN("Session is shutting down, waiting for termination of transactions\n");
		set_current_state(TASK_UNINTERRUPTIBLE);
		schedule_timeout(cfs_time_seconds(1));

		mutex_lock(&console_session.ses_mutex);
	}

	spin_lock(&console_session.ses_rpc_lock);

	lst_wait_until((atomic_read(&console_session.ses_rpc_counter) == 0),
		       console_session.ses_rpc_lock,
		       "Network is not accessible or target is down, waiting for %d console RPCs to being recycled\n",
		       atomic_read(&console_session.ses_rpc_counter));

	list_add(&zlist, &console_session.ses_rpc_freelist);
	list_del_init(&console_session.ses_rpc_freelist);

	spin_unlock(&console_session.ses_rpc_lock);

	while (!list_empty(&zlist)) {
		crpc = list_entry(zlist.next, lstcon_rpc_t, crp_link);

		list_del(&crpc->crp_link);
		LIBCFS_FREE(crpc, sizeof(lstcon_rpc_t));
	}
}

int
lstcon_rpc_module_init(void)
{
	INIT_LIST_HEAD(&console_session.ses_ping_timer.stt_list);
	console_session.ses_ping_timer.stt_func = lstcon_rpc_pinger;
	console_session.ses_ping_timer.stt_data = &console_session.ses_ping_timer;

	console_session.ses_ping = NULL;

	spin_lock_init(&console_session.ses_rpc_lock);
	atomic_set(&console_session.ses_rpc_counter, 0);
	INIT_LIST_HEAD(&console_session.ses_rpc_freelist);

	return 0;
}

void
lstcon_rpc_module_fini(void)
{
	LASSERT(list_empty(&console_session.ses_rpc_freelist));
	LASSERT(atomic_read(&console_session.ses_rpc_counter) == 0);
}
