/*
 * 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) 2012, Intel Corporation.
 */
/*
 * This file is part of Lustre, http://www.lustre.org/
 * Lustre is a trademark of Sun Microsystems, Inc.
 *
 * lnet/selftest/framework.c
 *
 * Author: Isaac Huang <isaac@clusterfs.com>
 * Author: Liang Zhen  <liangzhen@clusterfs.com>
 */

#define DEBUG_SUBSYSTEM S_LNET

#include "selftest.h"

lst_sid_t LST_INVALID_SID = {LNET_NID_ANY, -1};

static int session_timeout = 100;
CFS_MODULE_PARM(session_timeout, "i", int, 0444,
		"test session timeout in seconds (100 by default, 0 == never)");

static int rpc_timeout = 64;
CFS_MODULE_PARM(rpc_timeout, "i", int, 0644,
		"rpc timeout in seconds (64 by default, 0 == never)");

#define sfw_unpack_id(id)	       \
do {				    \
	__swab64s(&(id).nid);	   \
	__swab32s(&(id).pid);	   \
} while (0)

#define sfw_unpack_sid(sid)	     \
do {				    \
	__swab64s(&(sid).ses_nid);      \
	__swab64s(&(sid).ses_stamp);    \
} while (0)

#define sfw_unpack_fw_counters(fc)	\
do {				      \
	__swab32s(&(fc).running_ms);      \
	__swab32s(&(fc).active_batches);  \
	__swab32s(&(fc).zombie_sessions); \
	__swab32s(&(fc).brw_errors);      \
	__swab32s(&(fc).ping_errors);     \
} while (0)

#define sfw_unpack_rpc_counters(rc)     \
do {				    \
	__swab32s(&(rc).errors);	\
	__swab32s(&(rc).rpcs_sent);     \
	__swab32s(&(rc).rpcs_rcvd);     \
	__swab32s(&(rc).rpcs_dropped);  \
	__swab32s(&(rc).rpcs_expired);  \
	__swab64s(&(rc).bulk_get);      \
	__swab64s(&(rc).bulk_put);      \
} while (0)

#define sfw_unpack_lnet_counters(lc)    \
do {				    \
	__swab32s(&(lc).errors);	\
	__swab32s(&(lc).msgs_max);      \
	__swab32s(&(lc).msgs_alloc);    \
	__swab32s(&(lc).send_count);    \
	__swab32s(&(lc).recv_count);    \
	__swab32s(&(lc).drop_count);    \
	__swab32s(&(lc).route_count);   \
	__swab64s(&(lc).send_length);   \
	__swab64s(&(lc).recv_length);   \
	__swab64s(&(lc).drop_length);   \
	__swab64s(&(lc).route_length);  \
} while (0)

#define sfw_test_active(t)      (atomic_read(&(t)->tsi_nactive) != 0)
#define sfw_batch_active(b)     (atomic_read(&(b)->bat_nactive) != 0)

struct smoketest_framework {
	struct list_head	 fw_zombie_rpcs;     /* RPCs to be recycled */
	struct list_head	 fw_zombie_sessions; /* stopping sessions */
	struct list_head	 fw_tests;	   /* registered test cases */
	atomic_t       fw_nzombies;	/* # zombie sessions */
	spinlock_t	   fw_lock;		/* serialise */
	sfw_session_t	  *fw_session;		/* _the_ session */
	int		   fw_shuttingdown;	/* shutdown in progress */
	srpc_server_rpc_t *fw_active_srpc;	/* running RPC */
} sfw_data;

/* forward ref's */
int sfw_stop_batch (sfw_batch_t *tsb, int force);
void sfw_destroy_session (sfw_session_t *sn);

static inline sfw_test_case_t *
sfw_find_test_case(int id)
{
	sfw_test_case_t *tsc;

	LASSERT (id <= SRPC_SERVICE_MAX_ID);
	LASSERT (id > SRPC_FRAMEWORK_SERVICE_MAX_ID);

	list_for_each_entry (tsc, &sfw_data.fw_tests, tsc_list) {
		if (tsc->tsc_srv_service->sv_id == id)
			return tsc;
	}

	return NULL;
}

static int
sfw_register_test (srpc_service_t *service, sfw_test_client_ops_t *cliops)
{
	sfw_test_case_t *tsc;

	if (sfw_find_test_case(service->sv_id) != NULL) {
		CERROR ("Failed to register test %s (%d)\n",
			service->sv_name, service->sv_id);
		return -EEXIST;
	}

	LIBCFS_ALLOC(tsc, sizeof(sfw_test_case_t));
	if (tsc == NULL)
		return -ENOMEM;

	memset(tsc, 0, sizeof(sfw_test_case_t));
	tsc->tsc_cli_ops     = cliops;
	tsc->tsc_srv_service = service;

	list_add_tail(&tsc->tsc_list, &sfw_data.fw_tests);
	return 0;
}

void
sfw_add_session_timer (void)
{
	sfw_session_t *sn = sfw_data.fw_session;
	stt_timer_t   *timer = &sn->sn_timer;

	LASSERT (!sfw_data.fw_shuttingdown);

	if (sn == NULL || sn->sn_timeout == 0)
		return;

	LASSERT (!sn->sn_timer_active);

	sn->sn_timer_active = 1;
	timer->stt_expires = cfs_time_add(sn->sn_timeout,
					  cfs_time_current_sec());
	stt_add_timer(timer);
	return;
}

int
sfw_del_session_timer (void)
{
	sfw_session_t *sn = sfw_data.fw_session;

	if (sn == NULL || !sn->sn_timer_active)
		return 0;

	LASSERT (sn->sn_timeout != 0);

	if (stt_del_timer(&sn->sn_timer)) { /* timer defused */
		sn->sn_timer_active = 0;
		return 0;
	}

	return EBUSY; /* racing with sfw_session_expired() */
}

/* called with sfw_data.fw_lock held */
static void
sfw_deactivate_session (void)
{
	sfw_session_t *sn = sfw_data.fw_session;
	int	    nactive = 0;
	sfw_batch_t   *tsb;
	sfw_test_case_t *tsc;

	if (sn == NULL) return;

	LASSERT (!sn->sn_timer_active);

	sfw_data.fw_session = NULL;
	atomic_inc(&sfw_data.fw_nzombies);
	list_add(&sn->sn_list, &sfw_data.fw_zombie_sessions);

	spin_unlock(&sfw_data.fw_lock);

	list_for_each_entry(tsc, &sfw_data.fw_tests, tsc_list) {
		srpc_abort_service(tsc->tsc_srv_service);
	}

	spin_lock(&sfw_data.fw_lock);

	list_for_each_entry (tsb, &sn->sn_batches, bat_list) {
		if (sfw_batch_active(tsb)) {
			nactive++;
			sfw_stop_batch(tsb, 1);
		}
	}

	if (nactive != 0)
		return;   /* wait for active batches to stop */

	list_del_init(&sn->sn_list);
	spin_unlock(&sfw_data.fw_lock);

	sfw_destroy_session(sn);

	spin_lock(&sfw_data.fw_lock);
}


void
sfw_session_expired (void *data)
{
	sfw_session_t *sn = data;

	spin_lock(&sfw_data.fw_lock);

	LASSERT (sn->sn_timer_active);
	LASSERT (sn == sfw_data.fw_session);

	CWARN ("Session expired! sid: %s-"LPU64", name: %s\n",
	       libcfs_nid2str(sn->sn_id.ses_nid),
	       sn->sn_id.ses_stamp, &sn->sn_name[0]);

	sn->sn_timer_active = 0;
	sfw_deactivate_session();

	spin_unlock(&sfw_data.fw_lock);
}

static inline void
sfw_init_session(sfw_session_t *sn, lst_sid_t sid,
		 unsigned features, const char *name)
{
	stt_timer_t *timer = &sn->sn_timer;

	memset(sn, 0, sizeof(sfw_session_t));
	INIT_LIST_HEAD(&sn->sn_list);
	INIT_LIST_HEAD(&sn->sn_batches);
	atomic_set(&sn->sn_refcount, 1);	/* +1 for caller */
	atomic_set(&sn->sn_brw_errors, 0);
	atomic_set(&sn->sn_ping_errors, 0);
	strlcpy(&sn->sn_name[0], name, sizeof(sn->sn_name));

	sn->sn_timer_active = 0;
	sn->sn_id	   = sid;
	sn->sn_features	    = features;
	sn->sn_timeout      = session_timeout;
	sn->sn_started      = cfs_time_current();

	timer->stt_data = sn;
	timer->stt_func = sfw_session_expired;
	INIT_LIST_HEAD(&timer->stt_list);
}

/* completion handler for incoming framework RPCs */
void
sfw_server_rpc_done(struct srpc_server_rpc *rpc)
{
	struct srpc_service	*sv	= rpc->srpc_scd->scd_svc;
	int			status	= rpc->srpc_status;

	CDEBUG (D_NET,
		"Incoming framework RPC done: "
		"service %s, peer %s, status %s:%d\n",
		sv->sv_name, libcfs_id2str(rpc->srpc_peer),
		swi_state2str(rpc->srpc_wi.swi_state),
		status);

	if (rpc->srpc_bulk != NULL)
		sfw_free_pages(rpc);
	return;
}

void
sfw_client_rpc_fini (srpc_client_rpc_t *rpc)
{
	LASSERT (rpc->crpc_bulk.bk_niov == 0);
	LASSERT (list_empty(&rpc->crpc_list));
	LASSERT (atomic_read(&rpc->crpc_refcount) == 0);

	CDEBUG (D_NET,
		"Outgoing framework RPC done: "
		"service %d, peer %s, status %s:%d:%d\n",
		rpc->crpc_service, libcfs_id2str(rpc->crpc_dest),
		swi_state2str(rpc->crpc_wi.swi_state),
		rpc->crpc_aborted, rpc->crpc_status);

	spin_lock(&sfw_data.fw_lock);

	/* my callers must finish all RPCs before shutting me down */
	LASSERT(!sfw_data.fw_shuttingdown);
	list_add(&rpc->crpc_list, &sfw_data.fw_zombie_rpcs);

	spin_unlock(&sfw_data.fw_lock);
}

sfw_batch_t *
sfw_find_batch (lst_bid_t bid)
{
	sfw_session_t *sn = sfw_data.fw_session;
	sfw_batch_t   *bat;

	LASSERT (sn != NULL);

	list_for_each_entry (bat, &sn->sn_batches, bat_list) {
		if (bat->bat_id.bat_id == bid.bat_id)
			return bat;
	}

	return NULL;
}

sfw_batch_t *
sfw_bid2batch (lst_bid_t bid)
{
	sfw_session_t *sn = sfw_data.fw_session;
	sfw_batch_t   *bat;

	LASSERT (sn != NULL);

	bat = sfw_find_batch(bid);
	if (bat != NULL)
		return bat;

	LIBCFS_ALLOC(bat, sizeof(sfw_batch_t));
	if (bat == NULL)
		return NULL;

	bat->bat_error    = 0;
	bat->bat_session  = sn;
	bat->bat_id       = bid;
	atomic_set(&bat->bat_nactive, 0);
	INIT_LIST_HEAD(&bat->bat_tests);

	list_add_tail(&bat->bat_list, &sn->sn_batches);
	return bat;
}

int
sfw_get_stats (srpc_stat_reqst_t *request, srpc_stat_reply_t *reply)
{
	sfw_session_t  *sn = sfw_data.fw_session;
	sfw_counters_t *cnt = &reply->str_fw;
	sfw_batch_t    *bat;
	struct timeval  tv;

	reply->str_sid = (sn == NULL) ? LST_INVALID_SID : sn->sn_id;

	if (request->str_sid.ses_nid == LNET_NID_ANY) {
		reply->str_status = EINVAL;
		return 0;
	}

	if (sn == NULL || !sfw_sid_equal(request->str_sid, sn->sn_id)) {
		reply->str_status = ESRCH;
		return 0;
	}

	lnet_counters_get(&reply->str_lnet);
	srpc_get_counters(&reply->str_rpc);

	/* send over the msecs since the session was started
	 - with 32 bits to send, this is ~49 days */
	cfs_duration_usec(cfs_time_sub(cfs_time_current(),
				       sn->sn_started), &tv);

	cnt->running_ms      = (__u32)(tv.tv_sec * 1000 + tv.tv_usec / 1000);
	cnt->brw_errors      = atomic_read(&sn->sn_brw_errors);
	cnt->ping_errors     = atomic_read(&sn->sn_ping_errors);
	cnt->zombie_sessions = atomic_read(&sfw_data.fw_nzombies);

	cnt->active_batches = 0;
	list_for_each_entry (bat, &sn->sn_batches, bat_list) {
		if (atomic_read(&bat->bat_nactive) > 0)
			cnt->active_batches++;
	}

	reply->str_status = 0;
	return 0;
}

int
sfw_make_session(srpc_mksn_reqst_t *request, srpc_mksn_reply_t *reply)
{
	sfw_session_t *sn = sfw_data.fw_session;
	srpc_msg_t    *msg = container_of(request, srpc_msg_t,
					  msg_body.mksn_reqst);
	int	       cplen = 0;

	if (request->mksn_sid.ses_nid == LNET_NID_ANY) {
		reply->mksn_sid = (sn == NULL) ? LST_INVALID_SID : sn->sn_id;
		reply->mksn_status = EINVAL;
		return 0;
	}

	if (sn != NULL) {
		reply->mksn_status  = 0;
		reply->mksn_sid     = sn->sn_id;
		reply->mksn_timeout = sn->sn_timeout;

		if (sfw_sid_equal(request->mksn_sid, sn->sn_id)) {
			atomic_inc(&sn->sn_refcount);
			return 0;
		}

		if (!request->mksn_force) {
			reply->mksn_status = EBUSY;
			cplen = strlcpy(&reply->mksn_name[0], &sn->sn_name[0],
					sizeof(reply->mksn_name));
			if (cplen >= sizeof(reply->mksn_name))
				return -E2BIG;
			return 0;
		}
	}

	/* reject the request if it requires unknown features
	 * NB: old version will always accept all features because it's not
	 * aware of srpc_msg_t::msg_ses_feats, it's a defect but it's also
	 * harmless because it will return zero feature to console, and it's
	 * console's responsibility to make sure all nodes in a session have
	 * same feature mask. */
	if ((msg->msg_ses_feats & ~LST_FEATS_MASK) != 0) {
		reply->mksn_status = EPROTO;
		return 0;
	}

	/* brand new or create by force */
	LIBCFS_ALLOC(sn, sizeof(sfw_session_t));
	if (sn == NULL) {
		CERROR ("Dropping RPC (mksn) under memory pressure.\n");
		return -ENOMEM;
	}

	sfw_init_session(sn, request->mksn_sid,
			 msg->msg_ses_feats, &request->mksn_name[0]);

	spin_lock(&sfw_data.fw_lock);

	sfw_deactivate_session();
	LASSERT(sfw_data.fw_session == NULL);
	sfw_data.fw_session = sn;

	spin_unlock(&sfw_data.fw_lock);

	reply->mksn_status  = 0;
	reply->mksn_sid     = sn->sn_id;
	reply->mksn_timeout = sn->sn_timeout;
	return 0;
}

int
sfw_remove_session (srpc_rmsn_reqst_t *request, srpc_rmsn_reply_t *reply)
{
	sfw_session_t *sn = sfw_data.fw_session;

	reply->rmsn_sid = (sn == NULL) ? LST_INVALID_SID : sn->sn_id;

	if (request->rmsn_sid.ses_nid == LNET_NID_ANY) {
		reply->rmsn_status = EINVAL;
		return 0;
	}

	if (sn == NULL || !sfw_sid_equal(request->rmsn_sid, sn->sn_id)) {
		reply->rmsn_status = (sn == NULL) ? ESRCH : EBUSY;
		return 0;
	}

	if (!atomic_dec_and_test(&sn->sn_refcount)) {
		reply->rmsn_status = 0;
		return 0;
	}

	spin_lock(&sfw_data.fw_lock);
	sfw_deactivate_session();
	spin_unlock(&sfw_data.fw_lock);

	reply->rmsn_status = 0;
	reply->rmsn_sid    = LST_INVALID_SID;
	LASSERT(sfw_data.fw_session == NULL);
	return 0;
}

int
sfw_debug_session (srpc_debug_reqst_t *request, srpc_debug_reply_t *reply)
{
	sfw_session_t *sn = sfw_data.fw_session;

	if (sn == NULL) {
		reply->dbg_status = ESRCH;
		reply->dbg_sid    = LST_INVALID_SID;
		return 0;
	}

	reply->dbg_status  = 0;
	reply->dbg_sid     = sn->sn_id;
	reply->dbg_timeout = sn->sn_timeout;
	if (strlcpy(reply->dbg_name, &sn->sn_name[0], sizeof(reply->dbg_name))
	    >= sizeof(reply->dbg_name))
		return -E2BIG;

	return 0;
}

void
sfw_test_rpc_fini (srpc_client_rpc_t *rpc)
{
	sfw_test_unit_t     *tsu = rpc->crpc_priv;
	sfw_test_instance_t *tsi = tsu->tsu_instance;

	/* Called with hold of tsi->tsi_lock */
	LASSERT (list_empty(&rpc->crpc_list));
	list_add(&rpc->crpc_list, &tsi->tsi_free_rpcs);
}

static inline int
sfw_test_buffers(sfw_test_instance_t *tsi)
{
	struct sfw_test_case	*tsc = sfw_find_test_case(tsi->tsi_service);
	struct srpc_service	*svc = tsc->tsc_srv_service;
	int			nbuf;

	nbuf = min(svc->sv_wi_total, tsi->tsi_loop) / svc->sv_ncpts;
	return max(SFW_TEST_WI_MIN, nbuf + SFW_TEST_WI_EXTRA);
}

int
sfw_load_test(struct sfw_test_instance *tsi)
{
	struct sfw_test_case	*tsc;
	struct srpc_service	*svc;
	int			nbuf;
	int			rc;

	LASSERT(tsi != NULL);
	tsc = sfw_find_test_case(tsi->tsi_service);
	nbuf = sfw_test_buffers(tsi);
	LASSERT(tsc != NULL);
	svc = tsc->tsc_srv_service;

	if (tsi->tsi_is_client) {
		tsi->tsi_ops = tsc->tsc_cli_ops;
		return 0;
	}

	rc = srpc_service_add_buffers(svc, nbuf);
	if (rc != 0) {
		CWARN("Failed to reserve enough buffers: "
		      "service %s, %d needed: %d\n", svc->sv_name, nbuf, rc);
		/* NB: this error handler is not strictly correct, because
		 * it may release more buffers than already allocated,
		 * but it doesn't matter because request portal should
		 * be lazy portal and will grow buffers if necessary. */
		srpc_service_remove_buffers(svc, nbuf);
		return -ENOMEM;
	}

	CDEBUG(D_NET, "Reserved %d buffers for test %s\n",
	       nbuf * (srpc_serv_is_framework(svc) ?
		       1 : cfs_cpt_number(cfs_cpt_table)), svc->sv_name);
	return 0;
}

void
sfw_unload_test(struct sfw_test_instance *tsi)
{
	struct sfw_test_case *tsc = sfw_find_test_case(tsi->tsi_service);

	LASSERT(tsc != NULL);

	if (tsi->tsi_is_client)
		return;

	/* shrink buffers, because request portal is lazy portal
	 * which can grow buffers at runtime so we may leave
	 * some buffers behind, but never mind... */
	srpc_service_remove_buffers(tsc->tsc_srv_service,
				    sfw_test_buffers(tsi));
	return;
}

void
sfw_destroy_test_instance (sfw_test_instance_t *tsi)
{
	srpc_client_rpc_t *rpc;
	sfw_test_unit_t   *tsu;

	if (!tsi->tsi_is_client) goto clean;

	tsi->tsi_ops->tso_fini(tsi);

	LASSERT (!tsi->tsi_stopping);
	LASSERT (list_empty(&tsi->tsi_active_rpcs));
	LASSERT (!sfw_test_active(tsi));

	while (!list_empty(&tsi->tsi_units)) {
		tsu = list_entry(tsi->tsi_units.next,
				     sfw_test_unit_t, tsu_list);
		list_del(&tsu->tsu_list);
		LIBCFS_FREE(tsu, sizeof(*tsu));
	}

	while (!list_empty(&tsi->tsi_free_rpcs)) {
		rpc = list_entry(tsi->tsi_free_rpcs.next,
				     srpc_client_rpc_t, crpc_list);
		list_del(&rpc->crpc_list);
		LIBCFS_FREE(rpc, srpc_client_rpc_size(rpc));
	}

clean:
	sfw_unload_test(tsi);
	LIBCFS_FREE(tsi, sizeof(*tsi));
	return;
}

void
sfw_destroy_batch (sfw_batch_t *tsb)
{
	sfw_test_instance_t *tsi;

	LASSERT (!sfw_batch_active(tsb));
	LASSERT (list_empty(&tsb->bat_list));

	while (!list_empty(&tsb->bat_tests)) {
		tsi = list_entry(tsb->bat_tests.next,
				     sfw_test_instance_t, tsi_list);
		list_del_init(&tsi->tsi_list);
		sfw_destroy_test_instance(tsi);
	}

	LIBCFS_FREE(tsb, sizeof(sfw_batch_t));
	return;
}

void
sfw_destroy_session (sfw_session_t *sn)
{
	sfw_batch_t *batch;

	LASSERT (list_empty(&sn->sn_list));
	LASSERT (sn != sfw_data.fw_session);

	while (!list_empty(&sn->sn_batches)) {
		batch = list_entry(sn->sn_batches.next,
				       sfw_batch_t, bat_list);
		list_del_init(&batch->bat_list);
		sfw_destroy_batch(batch);
	}

	LIBCFS_FREE(sn, sizeof(*sn));
	atomic_dec(&sfw_data.fw_nzombies);
	return;
}

void
sfw_unpack_addtest_req(srpc_msg_t *msg)
{
	srpc_test_reqst_t *req = &msg->msg_body.tes_reqst;

	LASSERT (msg->msg_type == SRPC_MSG_TEST_REQST);
	LASSERT (req->tsr_is_client);

	if (msg->msg_magic == SRPC_MSG_MAGIC)
		return; /* no flipping needed */

	LASSERT (msg->msg_magic == __swab32(SRPC_MSG_MAGIC));

	if (req->tsr_service == SRPC_SERVICE_BRW) {
		if ((msg->msg_ses_feats & LST_FEAT_BULK_LEN) == 0) {
			test_bulk_req_t *bulk = &req->tsr_u.bulk_v0;

			__swab32s(&bulk->blk_opc);
			__swab32s(&bulk->blk_npg);
			__swab32s(&bulk->blk_flags);

		} else {
			test_bulk_req_v1_t *bulk = &req->tsr_u.bulk_v1;

			__swab16s(&bulk->blk_opc);
			__swab16s(&bulk->blk_flags);
			__swab32s(&bulk->blk_offset);
			__swab32s(&bulk->blk_len);
		}

		return;
	}

	if (req->tsr_service == SRPC_SERVICE_PING) {
		test_ping_req_t *ping = &req->tsr_u.ping;

		__swab32s(&ping->png_size);
		__swab32s(&ping->png_flags);
		return;
	}

	LBUG ();
	return;
}

int
sfw_add_test_instance (sfw_batch_t *tsb, srpc_server_rpc_t *rpc)
{
	srpc_msg_t	  *msg = &rpc->srpc_reqstbuf->buf_msg;
	srpc_test_reqst_t   *req = &msg->msg_body.tes_reqst;
	srpc_bulk_t	 *bk = rpc->srpc_bulk;
	int		  ndest = req->tsr_ndest;
	sfw_test_unit_t     *tsu;
	sfw_test_instance_t *tsi;
	int		  i;
	int		  rc;

	LIBCFS_ALLOC(tsi, sizeof(*tsi));
	if (tsi == NULL) {
		CERROR ("Can't allocate test instance for batch: "LPU64"\n",
			tsb->bat_id.bat_id);
		return -ENOMEM;
	}

	memset(tsi, 0, sizeof(*tsi));
	spin_lock_init(&tsi->tsi_lock);
	atomic_set(&tsi->tsi_nactive, 0);
	INIT_LIST_HEAD(&tsi->tsi_units);
	INIT_LIST_HEAD(&tsi->tsi_free_rpcs);
	INIT_LIST_HEAD(&tsi->tsi_active_rpcs);

	tsi->tsi_stopping      = 0;
	tsi->tsi_batch	 = tsb;
	tsi->tsi_loop	  = req->tsr_loop;
	tsi->tsi_concur	= req->tsr_concur;
	tsi->tsi_service       = req->tsr_service;
	tsi->tsi_is_client     = !!(req->tsr_is_client);
	tsi->tsi_stoptsu_onerr = !!(req->tsr_stop_onerr);

	rc = sfw_load_test(tsi);
	if (rc != 0) {
		LIBCFS_FREE(tsi, sizeof(*tsi));
		return rc;
	}

	LASSERT (!sfw_batch_active(tsb));

	if (!tsi->tsi_is_client) {
		/* it's test server, just add it to tsb */
		list_add_tail(&tsi->tsi_list, &tsb->bat_tests);
		return 0;
	}

	LASSERT (bk != NULL);
	LASSERT (bk->bk_niov * SFW_ID_PER_PAGE >= (unsigned int)ndest);
	LASSERT((unsigned int)bk->bk_len >=
		sizeof(lnet_process_id_packed_t) * ndest);

	sfw_unpack_addtest_req(msg);
	memcpy(&tsi->tsi_u, &req->tsr_u, sizeof(tsi->tsi_u));

	for (i = 0; i < ndest; i++) {
		lnet_process_id_packed_t *dests;
		lnet_process_id_packed_t  id;
		int		       j;

		dests = page_address(bk->bk_iovs[i / SFW_ID_PER_PAGE].kiov_page);
		LASSERT (dests != NULL);  /* my pages are within KVM always */
		id = dests[i % SFW_ID_PER_PAGE];
		if (msg->msg_magic != SRPC_MSG_MAGIC)
			sfw_unpack_id(id);

		for (j = 0; j < tsi->tsi_concur; j++) {
			LIBCFS_ALLOC(tsu, sizeof(sfw_test_unit_t));
			if (tsu == NULL) {
				rc = -ENOMEM;
				CERROR ("Can't allocate tsu for %d\n",
					tsi->tsi_service);
				goto error;
			}

			tsu->tsu_dest.nid = id.nid;
			tsu->tsu_dest.pid = id.pid;
			tsu->tsu_instance = tsi;
			tsu->tsu_private  = NULL;
			list_add_tail(&tsu->tsu_list, &tsi->tsi_units);
		}
	}

	rc = tsi->tsi_ops->tso_init(tsi);
	if (rc == 0) {
		list_add_tail(&tsi->tsi_list, &tsb->bat_tests);
		return 0;
	}

error:
	LASSERT (rc != 0);
	sfw_destroy_test_instance(tsi);
	return rc;
}

static void
sfw_test_unit_done (sfw_test_unit_t *tsu)
{
	sfw_test_instance_t *tsi = tsu->tsu_instance;
	sfw_batch_t	 *tsb = tsi->tsi_batch;
	sfw_session_t       *sn = tsb->bat_session;

	LASSERT (sfw_test_active(tsi));

	if (!atomic_dec_and_test(&tsi->tsi_nactive))
		return;

	/* the test instance is done */
	spin_lock(&tsi->tsi_lock);

	tsi->tsi_stopping = 0;

	spin_unlock(&tsi->tsi_lock);

	spin_lock(&sfw_data.fw_lock);

	if (!atomic_dec_and_test(&tsb->bat_nactive) ||/* tsb still active */
	    sn == sfw_data.fw_session) {		  /* sn also active */
		spin_unlock(&sfw_data.fw_lock);
		return;
	}

	LASSERT (!list_empty(&sn->sn_list)); /* I'm a zombie! */

	list_for_each_entry (tsb, &sn->sn_batches, bat_list) {
		if (sfw_batch_active(tsb)) {
			spin_unlock(&sfw_data.fw_lock);
			return;
		}
	}

	list_del_init(&sn->sn_list);
	spin_unlock(&sfw_data.fw_lock);

	sfw_destroy_session(sn);
	return;
}

void
sfw_test_rpc_done (srpc_client_rpc_t *rpc)
{
	sfw_test_unit_t     *tsu = rpc->crpc_priv;
	sfw_test_instance_t *tsi = tsu->tsu_instance;
	int		  done = 0;

	tsi->tsi_ops->tso_done_rpc(tsu, rpc);

	spin_lock(&tsi->tsi_lock);

	LASSERT (sfw_test_active(tsi));
	LASSERT (!list_empty(&rpc->crpc_list));

	list_del_init(&rpc->crpc_list);

	/* batch is stopping or loop is done or get error */
	if (tsi->tsi_stopping ||
	    tsu->tsu_loop == 0 ||
	    (rpc->crpc_status != 0 && tsi->tsi_stoptsu_onerr))
		done = 1;

	/* dec ref for poster */
	srpc_client_rpc_decref(rpc);

	spin_unlock(&tsi->tsi_lock);

	if (!done) {
		swi_schedule_workitem(&tsu->tsu_worker);
		return;
	}

	sfw_test_unit_done(tsu);
	return;
}

int
sfw_create_test_rpc(sfw_test_unit_t *tsu, lnet_process_id_t peer,
		    unsigned features, int nblk, int blklen,
		    srpc_client_rpc_t **rpcpp)
{
	srpc_client_rpc_t   *rpc = NULL;
	sfw_test_instance_t *tsi = tsu->tsu_instance;

	spin_lock(&tsi->tsi_lock);

	LASSERT (sfw_test_active(tsi));

	if (!list_empty(&tsi->tsi_free_rpcs)) {
		/* pick request from buffer */
		rpc = list_entry(tsi->tsi_free_rpcs.next,
				     srpc_client_rpc_t, crpc_list);
		LASSERT (nblk == rpc->crpc_bulk.bk_niov);
		list_del_init(&rpc->crpc_list);
	}

	spin_unlock(&tsi->tsi_lock);

	if (rpc == NULL) {
		rpc = srpc_create_client_rpc(peer, tsi->tsi_service, nblk,
					     blklen, sfw_test_rpc_done,
					     sfw_test_rpc_fini, tsu);
	} else {
		srpc_init_client_rpc(rpc, peer, tsi->tsi_service, nblk,
				     blklen, sfw_test_rpc_done,
				     sfw_test_rpc_fini, tsu);
	}

	if (rpc == NULL) {
		CERROR("Can't create rpc for test %d\n", tsi->tsi_service);
		return -ENOMEM;
	}

	rpc->crpc_reqstmsg.msg_ses_feats = features;
	*rpcpp = rpc;

	return 0;
}

int
sfw_run_test (swi_workitem_t *wi)
{
	sfw_test_unit_t     *tsu = wi->swi_workitem.wi_data;
	sfw_test_instance_t *tsi = tsu->tsu_instance;
	srpc_client_rpc_t   *rpc = NULL;

	LASSERT (wi == &tsu->tsu_worker);

	if (tsi->tsi_ops->tso_prep_rpc(tsu, tsu->tsu_dest, &rpc) != 0) {
		LASSERT (rpc == NULL);
		goto test_done;
	}

	LASSERT (rpc != NULL);

	spin_lock(&tsi->tsi_lock);

	if (tsi->tsi_stopping) {
		list_add(&rpc->crpc_list, &tsi->tsi_free_rpcs);
		spin_unlock(&tsi->tsi_lock);
		goto test_done;
	}

	if (tsu->tsu_loop > 0)
		tsu->tsu_loop--;

	list_add_tail(&rpc->crpc_list, &tsi->tsi_active_rpcs);
	spin_unlock(&tsi->tsi_lock);

	rpc->crpc_timeout = rpc_timeout;

	spin_lock(&rpc->crpc_lock);
	srpc_post_rpc(rpc);
	spin_unlock(&rpc->crpc_lock);
	return 0;

test_done:
	/*
	 * No one can schedule me now since:
	 * - previous RPC, if any, has done and
	 * - no new RPC is initiated.
	 * - my batch is still active; no one can run it again now.
	 * Cancel pending schedules and prevent future schedule attempts:
	 */
	swi_exit_workitem(wi);
	sfw_test_unit_done(tsu);
	return 1;
}

int
sfw_run_batch (sfw_batch_t *tsb)
{
	swi_workitem_t      *wi;
	sfw_test_unit_t     *tsu;
	sfw_test_instance_t *tsi;

	if (sfw_batch_active(tsb)) {
		CDEBUG(D_NET, "Batch already active: "LPU64" (%d)\n",
		       tsb->bat_id.bat_id, atomic_read(&tsb->bat_nactive));
		return 0;
	}

	list_for_each_entry (tsi, &tsb->bat_tests, tsi_list) {
		if (!tsi->tsi_is_client) /* skip server instances */
			continue;

		LASSERT (!tsi->tsi_stopping);
		LASSERT (!sfw_test_active(tsi));

		atomic_inc(&tsb->bat_nactive);

		list_for_each_entry (tsu, &tsi->tsi_units, tsu_list) {
			atomic_inc(&tsi->tsi_nactive);
			tsu->tsu_loop = tsi->tsi_loop;
			wi = &tsu->tsu_worker;
			swi_init_workitem(wi, tsu, sfw_run_test,
					  lst_sched_test[\
					  lnet_cpt_of_nid(tsu->tsu_dest.nid)]);
			swi_schedule_workitem(wi);
		}
	}

	return 0;
}

int
sfw_stop_batch (sfw_batch_t *tsb, int force)
{
	sfw_test_instance_t *tsi;
	srpc_client_rpc_t   *rpc;

	if (!sfw_batch_active(tsb)) {
		CDEBUG(D_NET, "Batch "LPU64" inactive\n", tsb->bat_id.bat_id);
		return 0;
	}

	list_for_each_entry (tsi, &tsb->bat_tests, tsi_list) {
		spin_lock(&tsi->tsi_lock);

		if (!tsi->tsi_is_client ||
		    !sfw_test_active(tsi) || tsi->tsi_stopping) {
			spin_unlock(&tsi->tsi_lock);
			continue;
		}

		tsi->tsi_stopping = 1;

		if (!force) {
			spin_unlock(&tsi->tsi_lock);
			continue;
		}

		/* abort launched rpcs in the test */
		list_for_each_entry(rpc, &tsi->tsi_active_rpcs, crpc_list) {
			spin_lock(&rpc->crpc_lock);

			srpc_abort_rpc(rpc, -EINTR);

			spin_unlock(&rpc->crpc_lock);
		}

		spin_unlock(&tsi->tsi_lock);
	}

	return 0;
}

int
sfw_query_batch (sfw_batch_t *tsb, int testidx, srpc_batch_reply_t *reply)
{
	sfw_test_instance_t *tsi;

	if (testidx < 0)
		return -EINVAL;

	if (testidx == 0) {
		reply->bar_active = atomic_read(&tsb->bat_nactive);
		return 0;
	}

	list_for_each_entry (tsi, &tsb->bat_tests, tsi_list) {
		if (testidx-- > 1)
			continue;

		reply->bar_active = atomic_read(&tsi->tsi_nactive);
		return 0;
	}

	return -ENOENT;
}

void
sfw_free_pages (srpc_server_rpc_t *rpc)
{
	srpc_free_bulk(rpc->srpc_bulk);
	rpc->srpc_bulk = NULL;
}

int
sfw_alloc_pages(struct srpc_server_rpc *rpc, int cpt, int npages, int len,
		int sink)
{
	LASSERT(rpc->srpc_bulk == NULL);
	LASSERT(npages > 0 && npages <= LNET_MAX_IOV);

	rpc->srpc_bulk = srpc_alloc_bulk(cpt, npages, len, sink);
	if (rpc->srpc_bulk == NULL)
		return -ENOMEM;

	return 0;
}

int
sfw_add_test (srpc_server_rpc_t *rpc)
{
	sfw_session_t     *sn = sfw_data.fw_session;
	srpc_test_reply_t *reply = &rpc->srpc_replymsg.msg_body.tes_reply;
	srpc_test_reqst_t *request;
	int		rc;
	sfw_batch_t       *bat;

	request = &rpc->srpc_reqstbuf->buf_msg.msg_body.tes_reqst;
	reply->tsr_sid = (sn == NULL) ? LST_INVALID_SID : sn->sn_id;

	if (request->tsr_loop == 0 ||
	    request->tsr_concur == 0 ||
	    request->tsr_sid.ses_nid == LNET_NID_ANY ||
	    request->tsr_ndest > SFW_MAX_NDESTS ||
	    (request->tsr_is_client && request->tsr_ndest == 0) ||
	    request->tsr_concur > SFW_MAX_CONCUR ||
	    request->tsr_service > SRPC_SERVICE_MAX_ID ||
	    request->tsr_service <= SRPC_FRAMEWORK_SERVICE_MAX_ID) {
		reply->tsr_status = EINVAL;
		return 0;
	}

	if (sn == NULL || !sfw_sid_equal(request->tsr_sid, sn->sn_id) ||
	    sfw_find_test_case(request->tsr_service) == NULL) {
		reply->tsr_status = ENOENT;
		return 0;
	}

	bat = sfw_bid2batch(request->tsr_bid);
	if (bat == NULL) {
		CERROR ("Dropping RPC (%s) from %s under memory pressure.\n",
			rpc->srpc_scd->scd_svc->sv_name,
			libcfs_id2str(rpc->srpc_peer));
		return -ENOMEM;
	}

	if (sfw_batch_active(bat)) {
		reply->tsr_status = EBUSY;
		return 0;
	}

	if (request->tsr_is_client && rpc->srpc_bulk == NULL) {
		/* rpc will be resumed later in sfw_bulk_ready */
		int	npg = sfw_id_pages(request->tsr_ndest);
		int	len;

		if ((sn->sn_features & LST_FEAT_BULK_LEN) == 0) {
			len = npg * PAGE_CACHE_SIZE;

		} else  {
			len = sizeof(lnet_process_id_packed_t) *
			      request->tsr_ndest;
		}

		return sfw_alloc_pages(rpc, CFS_CPT_ANY, npg, len, 1);
	}

	rc = sfw_add_test_instance(bat, rpc);
	CDEBUG (rc == 0 ? D_NET : D_WARNING,
		"%s test: sv %d %s, loop %d, concur %d, ndest %d\n",
		rc == 0 ? "Added" : "Failed to add", request->tsr_service,
		request->tsr_is_client ? "client" : "server",
		request->tsr_loop, request->tsr_concur, request->tsr_ndest);

	reply->tsr_status = (rc < 0) ? -rc : rc;
	return 0;
}

int
sfw_control_batch (srpc_batch_reqst_t *request, srpc_batch_reply_t *reply)
{
	sfw_session_t *sn = sfw_data.fw_session;
	int	    rc = 0;
	sfw_batch_t   *bat;

	reply->bar_sid = (sn == NULL) ? LST_INVALID_SID : sn->sn_id;

	if (sn == NULL || !sfw_sid_equal(request->bar_sid, sn->sn_id)) {
		reply->bar_status = ESRCH;
		return 0;
	}

	bat = sfw_find_batch(request->bar_bid);
	if (bat == NULL) {
		reply->bar_status = ENOENT;
		return 0;
	}

	switch (request->bar_opc) {
	case SRPC_BATCH_OPC_RUN:
		rc = sfw_run_batch(bat);
		break;

	case SRPC_BATCH_OPC_STOP:
		rc = sfw_stop_batch(bat, request->bar_arg);
		break;

	case SRPC_BATCH_OPC_QUERY:
		rc = sfw_query_batch(bat, request->bar_testidx, reply);
		break;

	default:
		return -EINVAL; /* drop it */
	}

	reply->bar_status = (rc < 0) ? -rc : rc;
	return 0;
}

int
sfw_handle_server_rpc(struct srpc_server_rpc *rpc)
{
	struct srpc_service	*sv = rpc->srpc_scd->scd_svc;
	srpc_msg_t     *reply	= &rpc->srpc_replymsg;
	srpc_msg_t     *request	= &rpc->srpc_reqstbuf->buf_msg;
	unsigned	features = LST_FEATS_MASK;
	int		rc = 0;

	LASSERT(sfw_data.fw_active_srpc == NULL);
	LASSERT(sv->sv_id <= SRPC_FRAMEWORK_SERVICE_MAX_ID);

	spin_lock(&sfw_data.fw_lock);

	if (sfw_data.fw_shuttingdown) {
		spin_unlock(&sfw_data.fw_lock);
		return -ESHUTDOWN;
	}

	/* Remove timer to avoid racing with it or expiring active session */
	if (sfw_del_session_timer() != 0) {
		CERROR("Dropping RPC (%s) from %s: racing with expiry timer.",
		       sv->sv_name, libcfs_id2str(rpc->srpc_peer));
		spin_unlock(&sfw_data.fw_lock);
		return -EAGAIN;
	}

	sfw_data.fw_active_srpc = rpc;
	spin_unlock(&sfw_data.fw_lock);

	sfw_unpack_message(request);
	LASSERT(request->msg_type == srpc_service2request(sv->sv_id));

	/* rpc module should have checked this */
	LASSERT(request->msg_version == SRPC_MSG_VERSION);

	if (sv->sv_id != SRPC_SERVICE_MAKE_SESSION &&
	    sv->sv_id != SRPC_SERVICE_DEBUG) {
		sfw_session_t *sn = sfw_data.fw_session;

		if (sn != NULL &&
		    sn->sn_features != request->msg_ses_feats) {
			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;
			goto out;
		}

	} else if ((request->msg_ses_feats & ~LST_FEATS_MASK) != 0) {
		/* NB: at this point, old version will ignore features and
		 * create new session anyway, so console should be able
		 * to handle this */
		reply->msg_body.reply.status = EPROTO;
		goto out;
	}

	switch(sv->sv_id) {
	default:
		LBUG ();
	case SRPC_SERVICE_TEST:
		rc = sfw_add_test(rpc);
		break;

	case SRPC_SERVICE_BATCH:
		rc = sfw_control_batch(&request->msg_body.bat_reqst,
				       &reply->msg_body.bat_reply);
		break;

	case SRPC_SERVICE_QUERY_STAT:
		rc = sfw_get_stats(&request->msg_body.stat_reqst,
				   &reply->msg_body.stat_reply);
		break;

	case SRPC_SERVICE_DEBUG:
		rc = sfw_debug_session(&request->msg_body.dbg_reqst,
				       &reply->msg_body.dbg_reply);
		break;

	case SRPC_SERVICE_MAKE_SESSION:
		rc = sfw_make_session(&request->msg_body.mksn_reqst,
				      &reply->msg_body.mksn_reply);
		break;

	case SRPC_SERVICE_REMOVE_SESSION:
		rc = sfw_remove_session(&request->msg_body.rmsn_reqst,
					&reply->msg_body.rmsn_reply);
		break;
	}

	if (sfw_data.fw_session != NULL)
		features = sfw_data.fw_session->sn_features;
 out:
	reply->msg_ses_feats = features;
	rpc->srpc_done = sfw_server_rpc_done;
	spin_lock(&sfw_data.fw_lock);

	if (!sfw_data.fw_shuttingdown)
		sfw_add_session_timer();

	sfw_data.fw_active_srpc = NULL;
	spin_unlock(&sfw_data.fw_lock);
	return rc;
}

int
sfw_bulk_ready(struct srpc_server_rpc *rpc, int status)
{
	struct srpc_service	*sv = rpc->srpc_scd->scd_svc;
	int			rc;

	LASSERT(rpc->srpc_bulk != NULL);
	LASSERT(sv->sv_id == SRPC_SERVICE_TEST);
	LASSERT(sfw_data.fw_active_srpc == NULL);
	LASSERT(rpc->srpc_reqstbuf->buf_msg.msg_body.tes_reqst.tsr_is_client);

	spin_lock(&sfw_data.fw_lock);

	if (status != 0) {
		CERROR("Bulk transfer failed for RPC: "
		       "service %s, peer %s, status %d\n",
		       sv->sv_name, libcfs_id2str(rpc->srpc_peer), status);
		spin_unlock(&sfw_data.fw_lock);
		return -EIO;
	}

	if (sfw_data.fw_shuttingdown) {
		spin_unlock(&sfw_data.fw_lock);
		return -ESHUTDOWN;
	}

	if (sfw_del_session_timer() != 0) {
		CERROR("Dropping RPC (%s) from %s: racing with expiry timer",
		       sv->sv_name, libcfs_id2str(rpc->srpc_peer));
		spin_unlock(&sfw_data.fw_lock);
		return -EAGAIN;
	}

	sfw_data.fw_active_srpc = rpc;
	spin_unlock(&sfw_data.fw_lock);

	rc = sfw_add_test(rpc);

	spin_lock(&sfw_data.fw_lock);

	if (!sfw_data.fw_shuttingdown)
		sfw_add_session_timer();

	sfw_data.fw_active_srpc = NULL;
	spin_unlock(&sfw_data.fw_lock);
	return rc;
}

srpc_client_rpc_t *
sfw_create_rpc(lnet_process_id_t peer, int service,
	       unsigned features, int nbulkiov, int bulklen,
	       void (*done)(srpc_client_rpc_t *), void *priv)
{
	srpc_client_rpc_t *rpc = NULL;

	spin_lock(&sfw_data.fw_lock);

	LASSERT (!sfw_data.fw_shuttingdown);
	LASSERT (service <= SRPC_FRAMEWORK_SERVICE_MAX_ID);

	if (nbulkiov == 0 && !list_empty(&sfw_data.fw_zombie_rpcs)) {
		rpc = list_entry(sfw_data.fw_zombie_rpcs.next,
				     srpc_client_rpc_t, crpc_list);
		list_del(&rpc->crpc_list);

		srpc_init_client_rpc(rpc, peer, service, 0, 0,
				     done, sfw_client_rpc_fini, priv);
	}

	spin_unlock(&sfw_data.fw_lock);

	if (rpc == NULL) {
		rpc = srpc_create_client_rpc(peer, service,
					     nbulkiov, bulklen, done,
					     nbulkiov != 0 ?  NULL :
					     sfw_client_rpc_fini,
					     priv);
	}

	if (rpc != NULL) /* "session" is concept in framework */
		rpc->crpc_reqstmsg.msg_ses_feats = features;

	return rpc;
}

void
sfw_unpack_message (srpc_msg_t *msg)
{
	if (msg->msg_magic == SRPC_MSG_MAGIC)
		return; /* no flipping needed */

	/* srpc module should guarantee I wouldn't get crap */
	LASSERT (msg->msg_magic == __swab32(SRPC_MSG_MAGIC));

	if (msg->msg_type == SRPC_MSG_STAT_REQST) {
		srpc_stat_reqst_t *req = &msg->msg_body.stat_reqst;

		__swab32s(&req->str_type);
		__swab64s(&req->str_rpyid);
		sfw_unpack_sid(req->str_sid);
		return;
	}

	if (msg->msg_type == SRPC_MSG_STAT_REPLY) {
		srpc_stat_reply_t *rep = &msg->msg_body.stat_reply;

		__swab32s(&rep->str_status);
		sfw_unpack_sid(rep->str_sid);
		sfw_unpack_fw_counters(rep->str_fw);
		sfw_unpack_rpc_counters(rep->str_rpc);
		sfw_unpack_lnet_counters(rep->str_lnet);
		return;
	}

	if (msg->msg_type == SRPC_MSG_MKSN_REQST) {
		srpc_mksn_reqst_t *req = &msg->msg_body.mksn_reqst;

		__swab64s(&req->mksn_rpyid);
		__swab32s(&req->mksn_force);
		sfw_unpack_sid(req->mksn_sid);
		return;
	}

	if (msg->msg_type == SRPC_MSG_MKSN_REPLY) {
		srpc_mksn_reply_t *rep = &msg->msg_body.mksn_reply;

		__swab32s(&rep->mksn_status);
		__swab32s(&rep->mksn_timeout);
		sfw_unpack_sid(rep->mksn_sid);
		return;
	}

	if (msg->msg_type == SRPC_MSG_RMSN_REQST) {
		srpc_rmsn_reqst_t *req = &msg->msg_body.rmsn_reqst;

		__swab64s(&req->rmsn_rpyid);
		sfw_unpack_sid(req->rmsn_sid);
		return;
	}

	if (msg->msg_type == SRPC_MSG_RMSN_REPLY) {
		srpc_rmsn_reply_t *rep = &msg->msg_body.rmsn_reply;

		__swab32s(&rep->rmsn_status);
		sfw_unpack_sid(rep->rmsn_sid);
		return;
	}

	if (msg->msg_type == SRPC_MSG_DEBUG_REQST) {
		srpc_debug_reqst_t *req = &msg->msg_body.dbg_reqst;

		__swab64s(&req->dbg_rpyid);
		__swab32s(&req->dbg_flags);
		sfw_unpack_sid(req->dbg_sid);
		return;
	}

	if (msg->msg_type == SRPC_MSG_DEBUG_REPLY) {
		srpc_debug_reply_t *rep = &msg->msg_body.dbg_reply;

		__swab32s(&rep->dbg_nbatch);
		__swab32s(&rep->dbg_timeout);
		sfw_unpack_sid(rep->dbg_sid);
		return;
	}

	if (msg->msg_type == SRPC_MSG_BATCH_REQST) {
		srpc_batch_reqst_t *req = &msg->msg_body.bat_reqst;

		__swab32s(&req->bar_opc);
		__swab64s(&req->bar_rpyid);
		__swab32s(&req->bar_testidx);
		__swab32s(&req->bar_arg);
		sfw_unpack_sid(req->bar_sid);
		__swab64s(&req->bar_bid.bat_id);
		return;
	}

	if (msg->msg_type == SRPC_MSG_BATCH_REPLY) {
		srpc_batch_reply_t *rep = &msg->msg_body.bat_reply;

		__swab32s(&rep->bar_status);
		sfw_unpack_sid(rep->bar_sid);
		return;
	}

	if (msg->msg_type == SRPC_MSG_TEST_REQST) {
		srpc_test_reqst_t *req = &msg->msg_body.tes_reqst;

		__swab64s(&req->tsr_rpyid);
		__swab64s(&req->tsr_bulkid);
		__swab32s(&req->tsr_loop);
		__swab32s(&req->tsr_ndest);
		__swab32s(&req->tsr_concur);
		__swab32s(&req->tsr_service);
		sfw_unpack_sid(req->tsr_sid);
		__swab64s(&req->tsr_bid.bat_id);
		return;
	}

	if (msg->msg_type == SRPC_MSG_TEST_REPLY) {
		srpc_test_reply_t *rep = &msg->msg_body.tes_reply;

		__swab32s(&rep->tsr_status);
		sfw_unpack_sid(rep->tsr_sid);
		return;
	}

	if (msg->msg_type == SRPC_MSG_JOIN_REQST) {
		srpc_join_reqst_t *req = &msg->msg_body.join_reqst;

		__swab64s(&req->join_rpyid);
		sfw_unpack_sid(req->join_sid);
		return;
	}

	if (msg->msg_type == SRPC_MSG_JOIN_REPLY) {
		srpc_join_reply_t *rep = &msg->msg_body.join_reply;

		__swab32s(&rep->join_status);
		__swab32s(&rep->join_timeout);
		sfw_unpack_sid(rep->join_sid);
		return;
	}

	LBUG ();
	return;
}

void
sfw_abort_rpc (srpc_client_rpc_t *rpc)
{
	LASSERT(atomic_read(&rpc->crpc_refcount) > 0);
	LASSERT(rpc->crpc_service <= SRPC_FRAMEWORK_SERVICE_MAX_ID);

	spin_lock(&rpc->crpc_lock);
	srpc_abort_rpc(rpc, -EINTR);
	spin_unlock(&rpc->crpc_lock);
	return;
}

void
sfw_post_rpc (srpc_client_rpc_t *rpc)
{
	spin_lock(&rpc->crpc_lock);

	LASSERT (!rpc->crpc_closed);
	LASSERT (!rpc->crpc_aborted);
	LASSERT (list_empty(&rpc->crpc_list));
	LASSERT (!sfw_data.fw_shuttingdown);

	rpc->crpc_timeout = rpc_timeout;
	srpc_post_rpc(rpc);

	spin_unlock(&rpc->crpc_lock);
	return;
}

static srpc_service_t sfw_services[] =
{
	{
		/* sv_id */    SRPC_SERVICE_DEBUG,
		/* sv_name */  "debug",
		0
	},
	{
		/* sv_id */    SRPC_SERVICE_QUERY_STAT,
		/* sv_name */  "query stats",
		0
	},
	{
		/* sv_id */    SRPC_SERVICE_MAKE_SESSION,
		/* sv_name */  "make session",
		0
	},
	{
		/* sv_id */    SRPC_SERVICE_REMOVE_SESSION,
		/* sv_name */  "remove session",
		0
	},
	{
		/* sv_id */    SRPC_SERVICE_BATCH,
		/* sv_name */  "batch service",
		0
	},
	{
		/* sv_id */    SRPC_SERVICE_TEST,
		/* sv_name */  "test service",
		0
	},
	{
		/* sv_id */    0,
		/* sv_name */  NULL,
		0
	}
};

extern sfw_test_client_ops_t ping_test_client;
extern srpc_service_t	ping_test_service;
extern void ping_init_test_client(void);
extern void ping_init_test_service(void);

extern sfw_test_client_ops_t brw_test_client;
extern srpc_service_t	brw_test_service;
extern void brw_init_test_client(void);
extern void brw_init_test_service(void);


int
sfw_startup (void)
{
	int	      i;
	int	      rc;
	int	      error;
	srpc_service_t  *sv;
	sfw_test_case_t *tsc;


	if (session_timeout < 0) {
		CERROR ("Session timeout must be non-negative: %d\n",
			session_timeout);
		return -EINVAL;
	}

	if (rpc_timeout < 0) {
		CERROR ("RPC timeout must be non-negative: %d\n",
			rpc_timeout);
		return -EINVAL;
	}

	if (session_timeout == 0)
		CWARN ("Zero session_timeout specified "
		       "- test sessions never expire.\n");

	if (rpc_timeout == 0)
		CWARN ("Zero rpc_timeout specified "
		       "- test RPC never expire.\n");

	memset(&sfw_data, 0, sizeof(struct smoketest_framework));

	sfw_data.fw_session     = NULL;
	sfw_data.fw_active_srpc = NULL;
	spin_lock_init(&sfw_data.fw_lock);
	atomic_set(&sfw_data.fw_nzombies, 0);
	INIT_LIST_HEAD(&sfw_data.fw_tests);
	INIT_LIST_HEAD(&sfw_data.fw_zombie_rpcs);
	INIT_LIST_HEAD(&sfw_data.fw_zombie_sessions);

	brw_init_test_client();
	brw_init_test_service();
	rc = sfw_register_test(&brw_test_service, &brw_test_client);
	LASSERT (rc == 0);

	ping_init_test_client();
	ping_init_test_service();
	rc = sfw_register_test(&ping_test_service, &ping_test_client);
	LASSERT (rc == 0);

	error = 0;
	list_for_each_entry (tsc, &sfw_data.fw_tests, tsc_list) {
		sv = tsc->tsc_srv_service;

		rc = srpc_add_service(sv);
		LASSERT (rc != -EBUSY);
		if (rc != 0) {
			CWARN ("Failed to add %s service: %d\n",
			       sv->sv_name, rc);
			error = rc;
		}
	}

	for (i = 0; ; i++) {
		sv = &sfw_services[i];
		if (sv->sv_name == NULL) break;

		sv->sv_bulk_ready = NULL;
		sv->sv_handler    = sfw_handle_server_rpc;
		sv->sv_wi_total   = SFW_FRWK_WI_MAX;
		if (sv->sv_id == SRPC_SERVICE_TEST)
			sv->sv_bulk_ready = sfw_bulk_ready;

		rc = srpc_add_service(sv);
		LASSERT (rc != -EBUSY);
		if (rc != 0) {
			CWARN ("Failed to add %s service: %d\n",
			       sv->sv_name, rc);
			error = rc;
		}

		/* about to sfw_shutdown, no need to add buffer */
		if (error) continue;

		rc = srpc_service_add_buffers(sv, sv->sv_wi_total);
		if (rc != 0) {
			CWARN("Failed to reserve enough buffers: "
			      "service %s, %d needed: %d\n",
			      sv->sv_name, sv->sv_wi_total, rc);
			error = -ENOMEM;
		}
	}

	if (error != 0)
		sfw_shutdown();
	return error;
}

void
sfw_shutdown (void)
{
	srpc_service_t	*sv;
	sfw_test_case_t	*tsc;
	int		 i;

	spin_lock(&sfw_data.fw_lock);

	sfw_data.fw_shuttingdown = 1;
	lst_wait_until(sfw_data.fw_active_srpc == NULL, sfw_data.fw_lock,
		       "waiting for active RPC to finish.\n");

	if (sfw_del_session_timer() != 0)
		lst_wait_until(sfw_data.fw_session == NULL, sfw_data.fw_lock,
			       "waiting for session timer to explode.\n");

	sfw_deactivate_session();
	lst_wait_until(atomic_read(&sfw_data.fw_nzombies) == 0,
		       sfw_data.fw_lock,
		       "waiting for %d zombie sessions to die.\n",
		       atomic_read(&sfw_data.fw_nzombies));

	spin_unlock(&sfw_data.fw_lock);

	for (i = 0; ; i++) {
		sv = &sfw_services[i];
		if (sv->sv_name == NULL)
			break;

		srpc_shutdown_service(sv);
		srpc_remove_service(sv);
	}

	list_for_each_entry (tsc, &sfw_data.fw_tests, tsc_list) {
		sv = tsc->tsc_srv_service;
		srpc_shutdown_service(sv);
		srpc_remove_service(sv);
	}

	while (!list_empty(&sfw_data.fw_zombie_rpcs)) {
		srpc_client_rpc_t *rpc;

		rpc = list_entry(sfw_data.fw_zombie_rpcs.next,
				     srpc_client_rpc_t, crpc_list);
		list_del(&rpc->crpc_list);

		LIBCFS_FREE(rpc, srpc_client_rpc_size(rpc));
	}

	for (i = 0; ; i++) {
		sv = &sfw_services[i];
		if (sv->sv_name == NULL)
			break;

		srpc_wait_service_shutdown(sv);
	}

	while (!list_empty(&sfw_data.fw_tests)) {
		tsc = list_entry(sfw_data.fw_tests.next,
				     sfw_test_case_t, tsc_list);

		srpc_wait_service_shutdown(tsc->tsc_srv_service);

		list_del(&tsc->tsc_list);
		LIBCFS_FREE(tsc, sizeof(*tsc));
	}

	return;
}
