-#else /* !__KERNEL__ */
-
-/* XXX
- * the current implementation of pinger in liblustre is not optimized
- */
-
-#ifdef ENABLE_PINGER
-static struct pinger_data {
- int pd_recursion;
- cfs_time_t pd_this_ping; /* jiffies */
- cfs_time_t pd_next_ping; /* jiffies */
- struct ptlrpc_request_set *pd_set;
-} pinger_args;
-
-static int pinger_check_rpcs(void *arg)
-{
- cfs_time_t curtime = cfs_time_current();
- struct ptlrpc_request *req;
- struct ptlrpc_request_set *set;
- struct list_head *iter;
- struct obd_import *imp;
- struct pinger_data *pd = &pinger_args;
- int rc;
-
- /* prevent recursion */
- if (pd->pd_recursion++) {
- CDEBUG(D_HA, "pinger: recursion! quit\n");
- LASSERT(pd->pd_set);
- pd->pd_recursion--;
- return 0;
- }
-
- /* have we reached ping point? */
- if (!pd->pd_set && cfs_time_before(curtime, pd->pd_next_ping)) {
- pd->pd_recursion--;
- return 0;
- }
-
- /* if we have rpc_set already, continue processing it */
- if (pd->pd_set) {
- LASSERT(pd->pd_this_ping);
- set = pd->pd_set;
- goto do_check_set;
- }
-
- pd->pd_this_ping = curtime;
- pd->pd_set = ptlrpc_prep_set();
- if (pd->pd_set == NULL)
- goto out;
- set = pd->pd_set;
-
- /* add rpcs into set */
- mutex_lock(&pinger_mutex);
- list_for_each(iter, &pinger_imports) {
- struct obd_import *imp = list_entry(iter, struct obd_import,
- imp_pinger_chain);
- int generation, level;
-
- if (cfs_time_aftereq(pd->pd_this_ping,
- imp->imp_next_ping - 5 * CFS_TICK)) {
- /* Add a ping. */
- spin_lock(&imp->imp_lock);
- generation = imp->imp_generation;
- level = imp->imp_state;
- spin_unlock(&imp->imp_lock);
-
- if (level != LUSTRE_IMP_FULL) {
- CDEBUG(D_HA,
- "not pinging %s (in recovery)\n",
- obd2cli_tgt(imp->imp_obd));
- continue;
- }
-
- req = ptlrpc_request_alloc_pack(imp, &RQF_OBD_PING,
- LUSTRE_OBD_VERSION,
- OBD_PING);
- if (req == NULL) {
- CERROR("OOM trying to ping %s->%s\n",
- imp->imp_obd->obd_uuid.uuid,
- obd2cli_tgt(imp->imp_obd));
- break;
- }
-
- req->rq_no_resend = 1;
- ptlrpc_request_set_replen(req);
- req->rq_send_state = LUSTRE_IMP_FULL;
- ptlrpc_rqphase_move(req, RQ_PHASE_RPC);
- req->rq_import_generation = generation;
- ptlrpc_set_add_req(set, req);
- } else {
- CDEBUG(D_INFO, "don't need to ping %s ("CFS_TIME_T
- " > "CFS_TIME_T")\n", obd2cli_tgt(imp->imp_obd),
- imp->imp_next_ping, pd->pd_this_ping);
- }
- }
- pd->pd_this_ping = curtime;
- mutex_unlock(&pinger_mutex);
-
- /* Might be empty, that's OK. */
- if (atomic_read(&set->set_remaining) == 0)
- CDEBUG(D_RPCTRACE, "nothing to ping\n");
-
- list_for_each(iter, &set->set_requests) {
- struct ptlrpc_request *req =
- list_entry(iter, struct ptlrpc_request,
- rq_set_chain);
- DEBUG_REQ(D_RPCTRACE, req, "pinging %s->%s",
- req->rq_import->imp_obd->obd_uuid.uuid,
- obd2cli_tgt(req->rq_import->imp_obd));
- (void)ptl_send_rpc(req, 0);
- }
-
-do_check_set:
- rc = ptlrpc_check_set(NULL, set);
-
- /* not finished, and we are not expired, simply return */
- if (!rc && cfs_time_before(curtime, cfs_time_add(pd->pd_this_ping,
- cfs_time_seconds(PING_INTERVAL)))) {
- CDEBUG(D_RPCTRACE, "not finished, but also not expired\n");
- pd->pd_recursion--;
- return 0;
- }
-
- /* Expire all the requests that didn't come back. */
- mutex_lock(&pinger_mutex);
- list_for_each(iter, &set->set_requests) {
- req = list_entry(iter, struct ptlrpc_request,
- rq_set_chain);
-
- if (req->rq_phase == RQ_PHASE_COMPLETE)
- continue;
-
- CDEBUG(D_RPCTRACE, "Pinger initiate expire request(%p)\n",
- req);
-
- /* This will also unregister reply. */
- ptlrpc_expire_one_request(req, 0);
-
- /* We're done with this req, let's finally move it to complete
- * phase and take care of inflights. */
- ptlrpc_rqphase_move(req, RQ_PHASE_COMPLETE);
- imp = req->rq_import;
- spin_lock(&imp->imp_lock);
- if (!list_empty(&req->rq_list)) {
- list_del_init(&req->rq_list);
- atomic_dec(&imp->imp_inflight);
- }
- spin_unlock(&imp->imp_lock);
- atomic_dec(&set->set_remaining);
- }
- mutex_unlock(&pinger_mutex);
-
- ptlrpc_set_destroy(set);
- pd->pd_set = NULL;
-
-out:
- pd->pd_next_ping = cfs_time_add(pd->pd_this_ping,
- cfs_time_seconds(PING_INTERVAL));
- pd->pd_this_ping = 0; /* XXX for debug */
-
- CDEBUG(D_INFO, "finished a round ping\n");
- pd->pd_recursion--;
- return 0;
-}
-
-static void *pinger_callback = NULL;
-#endif /* ENABLE_PINGER */
-
-int ptlrpc_start_pinger(void)
-{
-#ifdef ENABLE_PINGER
- memset(&pinger_args, 0, sizeof(pinger_args));
- pinger_callback = liblustre_register_wait_callback("pinger_check_rpcs",
- &pinger_check_rpcs,
- &pinger_args);
-#endif
- return 0;
-}
-
-int ptlrpc_stop_pinger(void)
-{
-#ifdef ENABLE_PINGER
- if (pinger_callback)
- liblustre_deregister_wait_callback(pinger_callback);
-#endif
- return 0;
-}
-
-void ptlrpc_pinger_sending_on_import(struct obd_import *imp)
-{
-#ifdef ENABLE_PINGER
- mutex_lock(&pinger_mutex);
- ptlrpc_update_next_ping(imp, 0);
- if (pinger_args.pd_set == NULL &&
- cfs_time_before(imp->imp_next_ping, pinger_args.pd_next_ping)) {
- CDEBUG(D_HA, "set next ping to "CFS_TIME_T"(cur "CFS_TIME_T")\n",
- imp->imp_next_ping, cfs_time_current());
- pinger_args.pd_next_ping = imp->imp_next_ping;
- }
- mutex_unlock(&pinger_mutex);
-#endif
-}
-
-void ptlrpc_pinger_commit_expected(struct obd_import *imp)
-{
-#ifdef ENABLE_PINGER
- mutex_lock(&pinger_mutex);
- ptlrpc_update_next_ping(imp, 1);
- if (pinger_args.pd_set == NULL &&
- cfs_time_before(imp->imp_next_ping, pinger_args.pd_next_ping)) {
- CDEBUG(D_HA,"set next ping to "CFS_TIME_T"(cur "CFS_TIME_T")\n",
- imp->imp_next_ping, cfs_time_current());
- pinger_args.pd_next_ping = imp->imp_next_ping;
- }
- mutex_unlock(&pinger_mutex);
-#endif
-}
-
-int ptlrpc_add_timeout_client(int time, enum timeout_event event,
- timeout_cb_t cb, void *data,
- struct list_head *obd_list)
-{
- return 0;
-}
-
-int ptlrpc_del_timeout_client(struct list_head *obd_list,
- enum timeout_event event)
-{
- return 0;
-}
-
-int ptlrpc_pinger_add_import(struct obd_import *imp)
-{
- ENTRY;
-
- if (!list_empty(&imp->imp_pinger_chain))
- RETURN(-EALREADY);
-
- CDEBUG(D_HA, "adding pingable import %s->%s\n",
- imp->imp_obd->obd_uuid.uuid, obd2cli_tgt(imp->imp_obd));
- ptlrpc_pinger_sending_on_import(imp);
-
- mutex_lock(&pinger_mutex);
- list_add_tail(&imp->imp_pinger_chain, &pinger_imports);
- class_import_get(imp);
- mutex_unlock(&pinger_mutex);
-
- RETURN(0);
-}
-
-int ptlrpc_pinger_del_import(struct obd_import *imp)
-{
- ENTRY;
-
- if (list_empty(&imp->imp_pinger_chain))
- RETURN(-ENOENT);
-
- mutex_lock(&pinger_mutex);
- list_del_init(&imp->imp_pinger_chain);
- CDEBUG(D_HA, "removing pingable import %s->%s\n",
- imp->imp_obd->obd_uuid.uuid, obd2cli_tgt(imp->imp_obd));
- class_import_put(imp);
- mutex_unlock(&pinger_mutex);
- RETURN(0);
-}
-
-void ptlrpc_pinger_wake_up()
-{
-#ifdef ENABLE_PINGER
- /* XXX force pinger to run, if needed */
- struct obd_import *imp;
- ENTRY;
- list_for_each_entry(imp, &pinger_imports, imp_pinger_chain) {
- CDEBUG(D_RPCTRACE, "checking import %s->%s\n",
- imp->imp_obd->obd_uuid.uuid, obd2cli_tgt(imp->imp_obd));
-#ifdef ENABLE_LIBLUSTRE_RECOVERY
- if (imp->imp_state == LUSTRE_IMP_DISCON &&
- !imp_is_deactive(imp))
-#else
- /*XXX only recover for the initial connection */
- if (!lustre_handle_is_used(&imp->imp_remote_handle) &&
- imp->imp_state == LUSTRE_IMP_DISCON &&
- !imp_is_deactive(imp))
-#endif
- ptlrpc_initiate_recovery(imp);
- else if (imp->imp_state != LUSTRE_IMP_FULL)
- CDEBUG(D_HA, "Refused to recover import %s->%s "
- "state %d, deactive %d\n",
- imp->imp_obd->obd_uuid.uuid,
- obd2cli_tgt(imp->imp_obd), imp->imp_state,
- imp_is_deactive(imp));
- }
- EXIT;
-#endif
-}
-#endif /* !__KERNEL__ */