- int rc = 0;
- char *tmpstr;
- char *s;
- const int tmpsiz = 256;
- int len;
- int ver;
- int num;
-
- DECLARE_LL_PROC_PPOS_DECL;
-
- num = LNET_PHASH_NUM_GET(*ppos);
- ver = LNET_VERSION_GET(*ppos);
-
- LASSERT (!write);
-
- if (*lenp == 0)
- return 0;
-
- LIBCFS_ALLOC(tmpstr, tmpsiz);
- if (tmpstr == NULL)
- return -ENOMEM;
-
- s = tmpstr; /* points to current position in tmpstr[] */
-
- if (*ppos == 0) {
- s += snprintf(s, tmpstr + tmpsiz - s,
- "%-4s %7s %9s %6s %12s %9s %8s %7s %s\n",
- "ref", "rtr_ref", "alive_cnt", "state", "last_ping",
- "ping_sent", "deadline", "down_ni", "router");
- LASSERT (tmpstr + tmpsiz - s > 0);
-
- LNET_LOCK();
- ver = (unsigned int)the_lnet.ln_routers_version;
- LNET_UNLOCK();
- *ppos = LNET_PHASH_POS_MAKE(ver, 0, num);
- } else {
- cfs_list_t *r;
- lnet_peer_t *peer = NULL;
- int skip = num - 1;
-
- LNET_LOCK();
-
- if (ver != LNET_VERSION_VALID_MASK(the_lnet.ln_routers_version)) {
- LNET_UNLOCK();
- LIBCFS_FREE(tmpstr, tmpsiz);
- return -ESTALE;
- }
-
- r = the_lnet.ln_routers.next;
-
- while (r != &the_lnet.ln_routers) {
- lnet_peer_t *lp = cfs_list_entry(r, lnet_peer_t,
- lp_rtr_list);
-
- if (skip == 0) {
- peer = lp;
- break;
- }
-
- skip--;
- r = r->next;
- }
-
- if (peer != NULL) {
- lnet_nid_t nid = peer->lp_nid;
- cfs_time_t now = cfs_time_current();
- cfs_time_t deadline = peer->lp_ping_deadline;
- int nrefs = peer->lp_refcount;
- int nrtrrefs = peer->lp_rtr_refcount;
- int alive_cnt = peer->lp_alive_count;
- int alive = peer->lp_alive;
- int pingsent = !peer->lp_ping_notsent;
- int last_ping = cfs_duration_sec(cfs_time_sub(now,
- peer->lp_ping_timestamp));
- int down_ni = lnet_router_down_ni(peer,
- LNET_NIDNET(LNET_NID_ANY));
-
- if (deadline == 0)
- s += snprintf(s, tmpstr + tmpsiz - s,
- "%-4d %7d %9d %6s %12d %9d %8s %7d %s\n",
- nrefs, nrtrrefs, alive_cnt,
- alive ? "up" : "down", last_ping,
- pingsent, "NA", down_ni,
- libcfs_nid2str(nid));
- else
- s += snprintf(s, tmpstr + tmpsiz - s,
- "%-4d %7d %9d %6s %12d %9d %8lu %7d %s\n",
- nrefs, nrtrrefs, alive_cnt,
- alive ? "up" : "down", last_ping,
- pingsent,
- cfs_duration_sec(cfs_time_sub(deadline, now)),
- down_ni, libcfs_nid2str(nid));
- LASSERT (tmpstr + tmpsiz - s > 0);
- }
-
- LNET_UNLOCK();
- }
-
- len = s - tmpstr; /* how many bytes was written */
-
- if (len > *lenp) { /* linux-supplied buffer is too small */
- rc = -EINVAL;
- } else if (len > 0) { /* wrote something */
- if (cfs_copy_to_user(buffer, tmpstr, len))
- rc = -EFAULT;
- else {
- num += 1;
- *ppos = LNET_PHASH_POS_MAKE(ver, 0, num);
- }
- }
-
- LIBCFS_FREE(tmpstr, tmpsiz);
-
- if (rc == 0)
- *lenp = len;
-
- return rc;