/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
* vim:expandtab:shiftwidth=8:tabstop=8:
*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*
* This file is part of Portals
* http://sourceforge.net/projects/sandiaportals/
#if defined(__KERNEL__) && defined(LNET_ROUTER)
-#include <linux/seq_file.h>
+/* This is really lnet_proc.c. You might need to update sanity test 215
+ * if any file format is changed. */
-/* this is really lnet_proc.c */
+static cfs_sysctl_table_header_t *lnet_table_header = NULL;
-#define LNET_PROC_STATS "sys/lnet/stats"
-#define LNET_PROC_ROUTES "sys/lnet/routes"
-#define LNET_PROC_ROUTERS "sys/lnet/routers"
-#define LNET_PROC_PEERS "sys/lnet/peers"
-#define LNET_PROC_BUFFERS "sys/lnet/buffers"
-#define LNET_PROC_NIS "sys/lnet/nis"
+#ifndef HAVE_SYSCTL_UNNUMBERED
+#define CTL_LNET (0x100)
+enum {
+ PSDEV_LNET_STATS = 100,
+ PSDEV_LNET_ROUTES,
+ PSDEV_LNET_ROUTERS,
+ PSDEV_LNET_PEERS,
+ PSDEV_LNET_BUFFERS,
+ PSDEV_LNET_NIS,
+};
+#else
+#define CTL_LNET CTL_UNNUMBERED
+#define PSDEV_LNET_STATS CTL_UNNUMBERED
+#define PSDEV_LNET_ROUTES CTL_UNNUMBERED
+#define PSDEV_LNET_ROUTERS CTL_UNNUMBERED
+#define PSDEV_LNET_PEERS CTL_UNNUMBERED
+#define PSDEV_LNET_BUFFERS CTL_UNNUMBERED
+#define PSDEV_LNET_NIS CTL_UNNUMBERED
+#endif
-static int
-lnet_router_proc_stats_read (char *page, char **start, off_t off,
- int count, int *eof, void *data)
+/*
+ * NB: we don't use the highest bit of *ppos because it's signed;
+ * next 9 bits is used to stash idx (assuming that
+ * LNET_PEER_HASHSIZE < 512)
+ */
+#define LNET_LOFFT_BITS (sizeof(loff_t) * 8)
+#define LNET_VERSION_BITS MAX(((MIN(LNET_LOFFT_BITS, 64)) / 4), 8)
+#define LNET_PHASH_IDX_BITS 9
+#define LNET_PHASH_NUM_BITS (LNET_LOFFT_BITS - 1 -\
+ LNET_VERSION_BITS - LNET_PHASH_IDX_BITS)
+#define LNET_PHASH_BITS (LNET_PHASH_IDX_BITS + LNET_PHASH_NUM_BITS)
+
+#define LNET_VERSION_BITMASK ((1ULL << LNET_VERSION_BITS) - 1)
+#define LNET_PHASH_IDX_BITMASK ((1ULL << LNET_PHASH_IDX_BITS) - 1)
+#define LNET_PHASH_NUM_BITMASK ((1ULL << LNET_PHASH_NUM_BITS) - 1)
+
+#define LNET_VERSION_MASK (LNET_VERSION_BITMASK << LNET_PHASH_BITS)
+#define LNET_PHASH_IDX_MASK (LNET_PHASH_IDX_BITMASK << LNET_PHASH_NUM_BITS)
+#define LNET_PHASH_NUM_MASK (LNET_PHASH_NUM_BITMASK)
+
+#define LNET_VERSION_GET(pos) (int)(((pos) & LNET_VERSION_MASK) >> \
+ LNET_PHASH_BITS)
+#define LNET_PHASH_IDX_GET(pos) (int)(((pos) & LNET_PHASH_IDX_MASK) >> \
+ LNET_PHASH_NUM_BITS)
+#define LNET_PHASH_NUM_GET(pos) (int)((pos) & LNET_PHASH_NUM_MASK)
+#define LNET_VERSION_VALID_MASK(ver) \
+ (unsigned int)((ver) & \
+ LNET_VERSION_BITMASK)
+#define LNET_PHASH_POS_MAKE(ver, idx, num) \
+ (((((loff_t)(ver)) & LNET_VERSION_BITMASK) << \
+ LNET_PHASH_BITS) | \
+ ((((loff_t)(idx)) & LNET_PHASH_IDX_BITMASK) <<\
+ LNET_PHASH_NUM_BITS) | \
+ ((num) & LNET_PHASH_NUM_BITMASK))
+
+static int __proc_lnet_stats(void *data, int write,
+ loff_t pos, void *buffer, int nob)
{
- lnet_counters_t *ctrs;
int rc;
+ lnet_counters_t *ctrs;
+ int len;
+ char *tmpstr;
+ const int tmpsiz = 256; /* 7 %u and 4 LPU64 */
- *start = page;
- *eof = 1;
- if (off != 0)
+ if (write) {
+ LNET_LOCK();
+ memset(&the_lnet.ln_counters, 0, sizeof(the_lnet.ln_counters));
+ LNET_UNLOCK();
return 0;
+ }
+
+ /* read */
LIBCFS_ALLOC(ctrs, sizeof(*ctrs));
if (ctrs == NULL)
return -ENOMEM;
+ LIBCFS_ALLOC(tmpstr, tmpsiz);
+ if (tmpstr == NULL) {
+ LIBCFS_FREE(ctrs, sizeof(*ctrs));
+ return -ENOMEM;
+ }
+
LNET_LOCK();
*ctrs = the_lnet.ln_counters;
LNET_UNLOCK();
- rc = sprintf(page,
- "%u %u %u %u %u %u %u "LPU64" "LPU64" "LPU64" "LPU64"\n",
- ctrs->msgs_alloc, ctrs->msgs_max,
- ctrs->errors,
- ctrs->send_count, ctrs->recv_count,
- ctrs->route_count, ctrs->drop_count,
- ctrs->send_length, ctrs->recv_length,
- ctrs->route_length, ctrs->drop_length);
-
+ len = snprintf(tmpstr, tmpsiz,
+ "%u %u %u %u %u %u %u "LPU64" "LPU64" "
+ LPU64" "LPU64,
+ ctrs->msgs_alloc, ctrs->msgs_max,
+ ctrs->errors,
+ ctrs->send_count, ctrs->recv_count,
+ ctrs->route_count, ctrs->drop_count,
+ ctrs->send_length, ctrs->recv_length,
+ ctrs->route_length, ctrs->drop_length);
+
+ if (pos >= min_t(int, len, strlen(tmpstr)))
+ rc = 0;
+ else
+ rc = cfs_trace_copyout_string(buffer, nob,
+ tmpstr + pos, "\n");
+
+ LIBCFS_FREE(tmpstr, tmpsiz);
LIBCFS_FREE(ctrs, sizeof(*ctrs));
return rc;
}
-static int
-lnet_router_proc_stats_write(struct file *file, const char *ubuffer,
- unsigned long count, void *data)
-{
- LNET_LOCK();
- memset(&the_lnet.ln_counters, 0, sizeof(the_lnet.ln_counters));
- LNET_UNLOCK();
-
- return (count);
-}
-
-typedef struct {
- __u64 lrsi_version;
- lnet_remotenet_t *lrsi_net;
- lnet_route_t *lrsi_route;
- loff_t lrsi_off;
-} lnet_route_seq_iterator_t;
+DECLARE_PROC_HANDLER(proc_lnet_stats);
-int
-lnet_route_seq_seek (lnet_route_seq_iterator_t *lrsi, loff_t off)
+int LL_PROC_PROTO(proc_lnet_routes)
{
- struct list_head *n;
- struct list_head *r;
- int rc;
- loff_t here;
-
- if (off == 0) {
- lrsi->lrsi_net = NULL;
- lrsi->lrsi_route = NULL;
- lrsi->lrsi_off = 0;
- return 0;
- }
+ int rc = 0;
+ char *tmpstr;
+ char *s;
+ const int tmpsiz = 256;
+ int len;
+ int ver;
+ int num;
- LNET_LOCK();
+ DECLARE_LL_PROC_PPOS_DECL;
- if (lrsi->lrsi_net != NULL &&
- lrsi->lrsi_version != the_lnet.ln_remote_nets_version) {
- /* tables have changed */
- rc = -ESTALE;
- goto out;
- }
+ num = LNET_PHASH_NUM_GET(*ppos);
+ ver = LNET_VERSION_GET(*ppos);
- if (lrsi->lrsi_net == NULL || lrsi->lrsi_off > off) {
- /* search from start */
- n = the_lnet.ln_remote_nets.next;
- r = NULL;
- here = 1;
- } else {
- /* continue search */
- n = &lrsi->lrsi_net->lrn_list;
- r = &lrsi->lrsi_route->lr_list;
- here = lrsi->lrsi_off;
- }
+ LASSERT (!write);
- lrsi->lrsi_version = the_lnet.ln_remote_nets_version;
- lrsi->lrsi_off = off;
+ if (*lenp == 0)
+ return 0;
- while (n != &the_lnet.ln_remote_nets) {
- lnet_remotenet_t *rnet =
- list_entry(n, lnet_remotenet_t, lrn_list);
+ LIBCFS_ALLOC(tmpstr, tmpsiz);
+ if (tmpstr == NULL)
+ return -ENOMEM;
- if (r == NULL)
- r = rnet->lrn_routes.next;
+ s = tmpstr; /* points to current position in tmpstr[] */
- while (r != &rnet->lrn_routes) {
- lnet_route_t *re =
- list_entry(r, lnet_route_t,
- lr_list);
+ if (*ppos == 0) {
+ s += snprintf(s, tmpstr + tmpsiz - s, "Routing %s\n",
+ the_lnet.ln_routing ? "enabled" : "disabled");
+ LASSERT (tmpstr + tmpsiz - s > 0);
- if (here == off) {
- lrsi->lrsi_net = rnet;
- lrsi->lrsi_route = re;
- rc = 0;
- goto out;
- }
+ s += snprintf(s, tmpstr + tmpsiz - s, "%-8s %4s %7s %s\n",
+ "net", "hops", "state", "router");
+ LASSERT (tmpstr + tmpsiz - s > 0);
- r = r->next;
- here++;
+ LNET_LOCK();
+ ver = (unsigned int)the_lnet.ln_remote_nets_version;
+ LNET_UNLOCK();
+ *ppos = LNET_PHASH_POS_MAKE(ver, 0, num);
+ } else {
+ cfs_list_t *n;
+ cfs_list_t *r;
+ lnet_route_t *route = NULL;
+ lnet_remotenet_t *rnet = NULL;
+ int skip = num - 1;
+
+ LNET_LOCK();
+
+ if (ver != LNET_VERSION_VALID_MASK(the_lnet.ln_remote_nets_version)) {
+ LNET_UNLOCK();
+ LIBCFS_FREE(tmpstr, tmpsiz);
+ return -ESTALE;
}
- r = NULL;
- n = n->next;
- }
-
- lrsi->lrsi_net = NULL;
- lrsi->lrsi_route = NULL;
- rc = -ENOENT;
- out:
- LNET_UNLOCK();
- return rc;
-}
-
-static void *
-lnet_route_seq_start (struct seq_file *s, loff_t *pos)
-{
- lnet_route_seq_iterator_t *lrsi;
- int rc;
-
- LIBCFS_ALLOC(lrsi, sizeof(*lrsi));
- if (lrsi == NULL)
- return NULL;
-
- lrsi->lrsi_net = NULL;
- rc = lnet_route_seq_seek(lrsi, *pos);
- if (rc == 0)
- return lrsi;
-
- LIBCFS_FREE(lrsi, sizeof(*lrsi));
- return NULL;
-}
-
-static void
-lnet_route_seq_stop (struct seq_file *s, void *iter)
-{
- lnet_route_seq_iterator_t *lrsi = iter;
+ n = the_lnet.ln_remote_nets.next;
- if (lrsi != NULL)
- LIBCFS_FREE(lrsi, sizeof(*lrsi));
-}
+ while (n != &the_lnet.ln_remote_nets && route == NULL) {
+ rnet = cfs_list_entry(n, lnet_remotenet_t, lrn_list);
-static void *
-lnet_route_seq_next (struct seq_file *s, void *iter, loff_t *pos)
-{
- lnet_route_seq_iterator_t *lrsi = iter;
- int rc;
- loff_t next = *pos + 1;
-
- rc = lnet_route_seq_seek(lrsi, next);
- if (rc != 0) {
- LIBCFS_FREE(lrsi, sizeof(*lrsi));
- return NULL;
- }
+ r = rnet->lrn_routes.next;
- *pos = next;
- return lrsi;
-}
+ while (r != &rnet->lrn_routes) {
+ lnet_route_t *re =
+ cfs_list_entry(r, lnet_route_t,
+ lr_list);
+ if (skip == 0) {
+ route = re;
+ break;
+ }
+
+ skip--;
+ r = r->next;
+ }
-static int
-lnet_route_seq_show (struct seq_file *s, void *iter)
-{
- lnet_route_seq_iterator_t *lrsi = iter;
- __u32 net;
- unsigned int hops;
- lnet_nid_t nid;
- int alive;
-
- if (lrsi->lrsi_off == 0) {
- seq_printf(s, "Routing %s\n",
- the_lnet.ln_routing ? "enabled" : "disabled");
- seq_printf(s, "%-8s %4s %7s %s\n",
- "net", "hops", "state", "router");
- return 0;
- }
+ n = n->next;
+ }
- LASSERT (lrsi->lrsi_net != NULL);
- LASSERT (lrsi->lrsi_route != NULL);
+ if (route != NULL) {
+ __u32 net = rnet->lrn_net;
+ unsigned int hops = route->lr_hops;
+ lnet_nid_t nid = route->lr_gateway->lp_nid;
+ int alive = route->lr_gateway->lp_alive;
- LNET_LOCK();
+ s += snprintf(s, tmpstr + tmpsiz - s, "%-8s %4u %7s %s\n",
+ libcfs_net2str(net), hops,
+ alive ? "up" : "down", libcfs_nid2str(nid));
+ LASSERT (tmpstr + tmpsiz - s > 0);
+ }
- if (lrsi->lrsi_version != the_lnet.ln_remote_nets_version) {
LNET_UNLOCK();
- return -ESTALE;
}
- net = lrsi->lrsi_net->lrn_net;
- hops = lrsi->lrsi_net->lrn_hops;
- nid = lrsi->lrsi_route->lr_gateway->lp_nid;
- alive = lrsi->lrsi_route->lr_gateway->lp_alive;
+ len = s - tmpstr; /* how many bytes was written */
- LNET_UNLOCK();
-
- seq_printf(s, "%-8s %4u %7s %s\n", libcfs_net2str(net), hops,
- alive ? "up" : "down", libcfs_nid2str(nid));
- return 0;
-}
-
-static struct seq_operations lnet_routes_sops = {
- .start = lnet_route_seq_start,
- .stop = lnet_route_seq_stop,
- .next = lnet_route_seq_next,
- .show = lnet_route_seq_show,
-};
-
-static int
-lnet_route_seq_open(struct inode *inode, struct file *file)
-{
- struct proc_dir_entry *dp = PDE(inode);
- struct seq_file *sf;
- int rc;
-
- rc = seq_open(file, &lnet_routes_sops);
- if (rc == 0) {
- sf = file->private_data;
- sf->private = dp->data;
- }
-
- return rc;
-}
-
-static struct file_operations lnet_routes_fops = {
- .owner = THIS_MODULE,
- .open = lnet_route_seq_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = seq_release,
-};
-
-typedef struct {
- __u64 lrtrsi_version;
- lnet_peer_t *lrtrsi_router;
- loff_t lrtrsi_off;
-} lnet_router_seq_iterator_t;
-
-int
-lnet_router_seq_seek (lnet_router_seq_iterator_t *lrtrsi, loff_t off)
-{
- struct list_head *r;
- lnet_peer_t *lp;
- int rc;
- loff_t here;
-
- if (off == 0) {
- lrtrsi->lrtrsi_router = NULL;
- lrtrsi->lrtrsi_off = 0;
- return 0;
- }
-
- LNET_LOCK();
-
- lp = lrtrsi->lrtrsi_router;
-
- if (lp != NULL &&
- lrtrsi->lrtrsi_version != the_lnet.ln_routers_version) {
- /* tables have changed */
- rc = -ESTALE;
- goto out;
- }
-
- if (lp == NULL || lrtrsi->lrtrsi_off > off) {
- /* search from start */
- r = the_lnet.ln_routers.next;
- here = 1;
- } else {
- /* continue search */
- r = &lp->lp_rtr_list;
- here = lrtrsi->lrtrsi_off;
- }
-
- lrtrsi->lrtrsi_version = the_lnet.ln_routers_version;
- lrtrsi->lrtrsi_off = off;
-
- while (r != &the_lnet.ln_routers) {
- lnet_peer_t *rtr = list_entry(r,
- lnet_peer_t,
- lp_rtr_list);
-
- if (here == off) {
- lrtrsi->lrtrsi_router = rtr;
- rc = 0;
- goto out;
+ 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);
}
-
- r = r->next;
- here++;
}
- lrtrsi->lrtrsi_router = NULL;
- rc = -ENOENT;
- out:
- LNET_UNLOCK();
- return rc;
-}
+ LIBCFS_FREE(tmpstr, tmpsiz);
-static void *
-lnet_router_seq_start (struct seq_file *s, loff_t *pos)
-{
- lnet_router_seq_iterator_t *lrtrsi;
- int rc;
-
- LIBCFS_ALLOC(lrtrsi, sizeof(*lrtrsi));
- if (lrtrsi == NULL)
- return NULL;
-
- lrtrsi->lrtrsi_router = NULL;
- rc = lnet_router_seq_seek(lrtrsi, *pos);
if (rc == 0)
- return lrtrsi;
+ *lenp = len;
- LIBCFS_FREE(lrtrsi, sizeof(*lrtrsi));
- return NULL;
+ return rc;
}
-static void
-lnet_router_seq_stop (struct seq_file *s, void *iter)
+int LL_PROC_PROTO(proc_lnet_routers)
{
- lnet_router_seq_iterator_t *lrtrsi = iter;
+ int rc = 0;
+ char *tmpstr;
+ char *s;
+ const int tmpsiz = 256;
+ int len;
+ int ver;
+ int num;
- if (lrtrsi != NULL)
- LIBCFS_FREE(lrtrsi, sizeof(*lrtrsi));
-}
+ DECLARE_LL_PROC_PPOS_DECL;
-static void *
-lnet_router_seq_next (struct seq_file *s, void *iter, loff_t *pos)
-{
- lnet_router_seq_iterator_t *lrtrsi = iter;
- int rc;
- loff_t next = *pos + 1;
-
- rc = lnet_router_seq_seek(lrtrsi, next);
- if (rc != 0) {
- LIBCFS_FREE(lrtrsi, sizeof(*lrtrsi));
- return NULL;
- }
+ num = LNET_PHASH_NUM_GET(*ppos);
+ ver = LNET_VERSION_GET(*ppos);
- *pos = next;
- return lrtrsi;
-}
+ LASSERT (!write);
-static int
-lnet_router_seq_show (struct seq_file *s, void *iter)
-{
- lnet_router_seq_iterator_t *lrtrsi = iter;
- lnet_peer_t *lp;
- lnet_nid_t nid;
- int alive;
- int alive_cnt;
- int nrefs;
- int nrtrrefs;
- time_t last_ping;
-
- if (lrtrsi->lrtrsi_off == 0) {
- seq_printf(s, "%-4s %7s %9s %6s %12s %s\n",
- "ref", "rtr_ref", "alive_cnt", "state", "last_ping", "router");
+ if (*lenp == 0)
return 0;
- }
-
- lp = lrtrsi->lrtrsi_router;
- LASSERT (lp != NULL);
-
- LNET_LOCK();
- if (lrtrsi->lrtrsi_version != the_lnet.ln_routers_version) {
- LNET_UNLOCK();
- return -ESTALE;
- }
+ LIBCFS_ALLOC(tmpstr, tmpsiz);
+ if (tmpstr == NULL)
+ return -ENOMEM;
- nid = lp->lp_nid;
- alive = lp->lp_alive;
- alive_cnt = lp->lp_alive_count;
- nrefs = lp->lp_refcount;
- nrtrrefs = lp->lp_rtr_refcount;
- last_ping = lp->lp_ping_timestamp;
+ s = tmpstr; /* points to current position in tmpstr[] */
- LNET_UNLOCK();
+ 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);
- seq_printf(s,
- "%-4d %7d %9d %6s %12lu %s\n", nrefs, nrtrrefs,
- alive_cnt, alive ? "up" : "down",
- last_ping, libcfs_nid2str(nid));
- return 0;
-}
-
-static struct seq_operations lnet_routers_sops = {
- .start = lnet_router_seq_start,
- .stop = lnet_router_seq_stop,
- .next = lnet_router_seq_next,
- .show = lnet_router_seq_show,
-};
+ 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;
-static int
-lnet_router_seq_open(struct inode *inode, struct file *file)
-{
- struct proc_dir_entry *dp = PDE(inode);
- struct seq_file *sf;
- int rc;
-
- rc = seq_open(file, &lnet_routers_sops);
- if (rc == 0) {
- sf = file->private_data;
- sf->private = dp->data;
- }
+ LNET_LOCK();
- return rc;
-}
+ if (ver != LNET_VERSION_VALID_MASK(the_lnet.ln_routers_version)) {
+ LNET_UNLOCK();
+ LIBCFS_FREE(tmpstr, tmpsiz);
+ return -ESTALE;
+ }
-static struct file_operations lnet_routers_fops = {
- .owner = THIS_MODULE,
- .open = lnet_router_seq_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = seq_release,
-};
+ r = the_lnet.ln_routers.next;
-typedef struct {
- unsigned long long lpsi_version;
- int lpsi_idx;
- lnet_peer_t *lpsi_peer;
- loff_t lpsi_off;
-} lnet_peer_seq_iterator_t;
+ while (r != &the_lnet.ln_routers) {
+ lnet_peer_t *lp = cfs_list_entry(r, lnet_peer_t,
+ lp_rtr_list);
-int
-lnet_peer_seq_seek (lnet_peer_seq_iterator_t *lpsi, loff_t off)
-{
- int idx;
- struct list_head *p;
- loff_t here;
- int rc;
-
- if (off == 0) {
- lpsi->lpsi_idx = 0;
- lpsi->lpsi_peer = NULL;
- lpsi->lpsi_off = 0;
- return 0;
- }
+ if (skip == 0) {
+ peer = lp;
+ break;
+ }
- LNET_LOCK();
+ skip--;
+ r = r->next;
+ }
- if (lpsi->lpsi_peer != NULL &&
- lpsi->lpsi_version != the_lnet.ln_peertable_version) {
- /* tables have changed */
- rc = -ESTALE;
- goto out;
- }
+ 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);
+ }
- if (lpsi->lpsi_peer == NULL ||
- lpsi->lpsi_off > off) {
- /* search from start */
- idx = 0;
- p = NULL;
- here = 1;
- } else {
- /* continue search */
- idx = lpsi->lpsi_idx;
- p = &lpsi->lpsi_peer->lp_hashlist;
- here = lpsi->lpsi_off;
+ LNET_UNLOCK();
}
- lpsi->lpsi_version = the_lnet.ln_peertable_version;
- lpsi->lpsi_off = off;
-
- while (idx < LNET_PEER_HASHSIZE) {
- if (p == NULL)
- p = the_lnet.ln_peer_hash[idx].next;
+ len = s - tmpstr; /* how many bytes was written */
- while (p != &the_lnet.ln_peer_hash[idx]) {
- lnet_peer_t *lp = list_entry(p, lnet_peer_t,
- lp_hashlist);
-
- if (here == off) {
- lpsi->lpsi_idx = idx;
- lpsi->lpsi_peer = lp;
- rc = 0;
- goto out;
- }
-
- here++;
- p = lp->lp_hashlist.next;
+ 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);
}
-
- p = NULL;
- idx++;
}
- lpsi->lpsi_idx = 0;
- lpsi->lpsi_peer = NULL;
- rc = -ENOENT;
- out:
- LNET_UNLOCK();
- return rc;
-}
-
-static void *
-lnet_peer_seq_start (struct seq_file *s, loff_t *pos)
-{
- lnet_peer_seq_iterator_t *lpsi;
- int rc;
+ LIBCFS_FREE(tmpstr, tmpsiz);
- LIBCFS_ALLOC(lpsi, sizeof(*lpsi));
- if (lpsi == NULL)
- return NULL;
-
- lpsi->lpsi_idx = 0;
- lpsi->lpsi_peer = NULL;
- rc = lnet_peer_seq_seek(lpsi, *pos);
if (rc == 0)
- return lpsi;
-
- LIBCFS_FREE(lpsi, sizeof(*lpsi));
- return NULL;
-}
-
-static void
-lnet_peer_seq_stop (struct seq_file *s, void *iter)
-{
- lnet_peer_seq_iterator_t *lpsi = iter;
+ *lenp = len;
- if (lpsi != NULL)
- LIBCFS_FREE(lpsi, sizeof(*lpsi));
+ return rc;
}
-static void *
-lnet_peer_seq_next (struct seq_file *s, void *iter, loff_t *pos)
+int LL_PROC_PROTO(proc_lnet_peers)
{
- lnet_peer_seq_iterator_t *lpsi = iter;
- int rc;
- loff_t next = *pos + 1;
-
- rc = lnet_peer_seq_seek(lpsi, next);
- if (rc != 0) {
- LIBCFS_FREE(lpsi, sizeof(*lpsi));
- return NULL;
- }
+ int rc = 0;
+ char *tmpstr;
+ char *s;
+ const int tmpsiz = 256;
+ int len;
+ int ver;
+ int idx;
+ int num;
- *pos = next;
- return lpsi;
-}
+ DECLARE_LL_PROC_PPOS_DECL;
-static int
-lnet_peer_seq_show (struct seq_file *s, void *iter)
-{
- lnet_peer_seq_iterator_t *lpsi = iter;
- lnet_peer_t *lp;
- lnet_nid_t nid;
- int maxcr;
- int mintxcr;
- int txcr;
- int minrtrcr;
- int rtrcr;
- int alive;
- int rtr;
- int txqnob;
- int nrefs;
-
- if (lpsi->lpsi_off == 0) {
- seq_printf(s, "%-24s %4s %5s %5s %5s %5s %5s %5s %s\n",
- "nid", "refs", "state", "max",
- "rtr", "min", "tx", "min", "queue");
- return 0;
- }
+ idx = LNET_PHASH_IDX_GET(*ppos);
+ num = LNET_PHASH_NUM_GET(*ppos);
+ ver = LNET_VERSION_GET(*ppos);
- LASSERT (lpsi->lpsi_peer != NULL);
+ CLASSERT ((1ULL << LNET_PHASH_BITS) > LNET_PEER_HASHSIZE);
- LNET_LOCK();
+ LASSERT (!write);
- if (lpsi->lpsi_version != the_lnet.ln_peertable_version) {
- LNET_UNLOCK();
- return -ESTALE;
- }
+ if (*lenp == 0)
+ return 0;
- lp = lpsi->lpsi_peer;
+ LIBCFS_ALLOC(tmpstr, tmpsiz);
+ if (tmpstr == NULL)
+ return -ENOMEM;
- nid = lp->lp_nid;
- maxcr = lp->lp_ni->ni_peertxcredits;
- txcr = lp->lp_txcredits;
- mintxcr = lp->lp_mintxcredits;
- rtrcr = lp->lp_rtrcredits;
- minrtrcr = lp->lp_minrtrcredits;
- rtr = lnet_isrouter(lp);
- alive = lp->lp_alive;
- txqnob = lp->lp_txqnob;
- nrefs = lp->lp_refcount;
+ s = tmpstr; /* points to current position in tmpstr[] */
- LNET_UNLOCK();
+ if (*ppos == 0) {
+ s += snprintf(s, tmpstr + tmpsiz - s,
+ "%-24s %4s %5s %5s %5s %5s %5s %5s %5s %s\n",
+ "nid", "refs", "state", "last", "max",
+ "rtr", "min", "tx", "min", "queue");
+ LASSERT (tmpstr + tmpsiz - s > 0);
- seq_printf(s, "%-24s %4d %5s %5d %5d %5d %5d %5d %d\n",
- libcfs_nid2str(nid), nrefs,
- !rtr ? "~rtr" : (alive ? "up" : "down"),
- maxcr, rtrcr, minrtrcr, txcr, mintxcr, txqnob);
- return 0;
-}
+ LNET_LOCK();
+ ver = (unsigned int)the_lnet.ln_peertable_version;
+ LNET_UNLOCK();
+ *ppos = LNET_PHASH_POS_MAKE(ver, idx, num);
-static struct seq_operations lnet_peer_sops = {
- .start = lnet_peer_seq_start,
- .stop = lnet_peer_seq_stop,
- .next = lnet_peer_seq_next,
- .show = lnet_peer_seq_show,
-};
+ num++;
+ } else {
+ cfs_list_t *p = NULL;
+ lnet_peer_t *peer = NULL;
+ int skip = num - 1;
-static int
-lnet_peer_seq_open(struct inode *inode, struct file *file)
-{
- struct proc_dir_entry *dp = PDE(inode);
- struct seq_file *sf;
- int rc;
-
- rc = seq_open(file, &lnet_peer_sops);
- if (rc == 0) {
- sf = file->private_data;
- sf->private = dp->data;
- }
+ LNET_LOCK();
- return rc;
-}
+ if (ver != LNET_VERSION_VALID_MASK(the_lnet.ln_peertable_version)) {
+ LNET_UNLOCK();
+ LIBCFS_FREE(tmpstr, tmpsiz);
+ return -ESTALE;
+ }
-static struct file_operations lnet_peer_fops = {
- .owner = THIS_MODULE,
- .open = lnet_peer_seq_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = seq_release,
-};
+ while (idx < LNET_PEER_HASHSIZE) {
+ if (p == NULL)
+ p = the_lnet.ln_peer_hash[idx].next;
+
+ while (p != &the_lnet.ln_peer_hash[idx]) {
+ lnet_peer_t *lp = cfs_list_entry(p, lnet_peer_t,
+ lp_hashlist);
+ if (skip == 0) {
+ peer = lp;
+
+ /* minor optimization: start from idx+1
+ * on next iteration if we've just
+ * drained lp_hashlist */
+ if (lp->lp_hashlist.next ==
+ &the_lnet.ln_peer_hash[idx]) {
+ num = 1;
+ idx++;
+ } else {
+ num++;
+ }
+
+ break;
+ }
+
+ skip--;
+ p = lp->lp_hashlist.next;
+ }
-typedef struct {
- int lbsi_idx;
- loff_t lbsi_off;
-} lnet_buffer_seq_iterator_t;
+ if (peer != NULL)
+ break;
-int
-lnet_buffer_seq_seek (lnet_buffer_seq_iterator_t *lbsi, loff_t off)
-{
- int idx;
- loff_t here;
- int rc;
+ p = NULL;
+ num = 1;
+ idx++;
+ }
- if (off == 0) {
- lbsi->lbsi_idx = -1;
- lbsi->lbsi_off = 0;
- return 0;
- }
+ if (peer != NULL) {
+ lnet_nid_t nid = peer->lp_nid;
+ int nrefs = peer->lp_refcount;
+ int lastalive = -1;
+ char *aliveness = "NA";
+ int maxcr = peer->lp_ni->ni_peertxcredits;
+ int txcr = peer->lp_txcredits;
+ int mintxcr = peer->lp_mintxcredits;
+ int rtrcr = peer->lp_rtrcredits;
+ int minrtrcr = peer->lp_minrtrcredits;
+ int txqnob = peer->lp_txqnob;
+
+ if (lnet_isrouter(peer) ||
+ lnet_peer_aliveness_enabled(peer))
+ aliveness = peer->lp_alive ? "up" : "down";
+
+ if (lnet_peer_aliveness_enabled(peer)) {
+ cfs_time_t now = cfs_time_current();
+ cfs_duration_t delta;
+
+ delta = cfs_time_sub(now, peer->lp_last_alive);
+ lastalive = cfs_duration_sec(delta);
+
+ /* No need to mess up peers contents with
+ * arbitrarily long integers - it suffices to
+ * know that lastalive is more than 10000s old
+ */
+ if (lastalive >= 10000)
+ lastalive = 9999;
+ }
- LNET_LOCK();
+ s += snprintf(s, tmpstr + tmpsiz - s,
+ "%-24s %4d %5s %5d %5d %5d %5d %5d %5d %d\n",
+ libcfs_nid2str(nid), nrefs, aliveness,
+ lastalive, maxcr, rtrcr, minrtrcr, txcr,
+ mintxcr, txqnob);
+ LASSERT (tmpstr + tmpsiz - s > 0);
+ }
- if (lbsi->lbsi_idx < 0 ||
- lbsi->lbsi_off > off) {
- /* search from start */
- idx = 0;
- here = 1;
- } else {
- /* continue search */
- idx = lbsi->lbsi_idx;
- here = lbsi->lbsi_off;
+ LNET_UNLOCK();
}
- lbsi->lbsi_off = off;
+ len = s - tmpstr; /* how many bytes was written */
- while (idx < LNET_NRBPOOLS) {
- if (here == off) {
- lbsi->lbsi_idx = idx;
- rc = 0;
- goto out;
- }
- here++;
- idx++;
+ 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
+ *ppos = LNET_PHASH_POS_MAKE(ver, idx, num);
}
- lbsi->lbsi_idx = -1;
- rc = -ENOENT;
- out:
- LNET_UNLOCK();
- return rc;
-}
-
-static void *
-lnet_buffer_seq_start (struct seq_file *s, loff_t *pos)
-{
- lnet_buffer_seq_iterator_t *lbsi;
- int rc;
-
- LIBCFS_ALLOC(lbsi, sizeof(*lbsi));
- if (lbsi == NULL)
- return NULL;
+ LIBCFS_FREE(tmpstr, tmpsiz);
- lbsi->lbsi_idx = -1;
- rc = lnet_buffer_seq_seek(lbsi, *pos);
if (rc == 0)
- return lbsi;
+ *lenp = len;
- LIBCFS_FREE(lbsi, sizeof(*lbsi));
- return NULL;
+ return rc;
}
-static void
-lnet_buffer_seq_stop (struct seq_file *s, void *iter)
+static int __proc_lnet_buffers(void *data, int write,
+ loff_t pos, void *buffer, int nob)
{
- lnet_buffer_seq_iterator_t *lbsi = iter;
- if (lbsi != NULL)
- LIBCFS_FREE(lbsi, sizeof(*lbsi));
-}
+ int rc;
+ int len;
+ char *s;
+ char *tmpstr;
+ const int tmpsiz = 64 * (LNET_NRBPOOLS + 1); /* (4 %d) * 4 */
+ int idx;
-static void *
-lnet_buffer_seq_next (struct seq_file *s, void *iter, loff_t *pos)
-{
- lnet_buffer_seq_iterator_t *lbsi = iter;
- int rc;
- loff_t next = *pos + 1;
-
- rc = lnet_buffer_seq_seek(lbsi, next);
- if (rc != 0) {
- LIBCFS_FREE(lbsi, sizeof(*lbsi));
- return NULL;
- }
+ LASSERT (!write);
- *pos = next;
- return lbsi;
-}
+ LIBCFS_ALLOC(tmpstr, tmpsiz);
+ if (tmpstr == NULL)
+ return -ENOMEM;
-static int
-lnet_buffer_seq_show (struct seq_file *s, void *iter)
-{
- lnet_buffer_seq_iterator_t *lbsi = iter;
- lnet_rtrbufpool_t *rbp;
- int npages;
- int nbuf;
- int cr;
- int mincr;
-
- if (lbsi->lbsi_off == 0) {
- seq_printf(s, "%5s %5s %7s %7s\n",
- "pages", "count", "credits", "min");
- return 0;
- }
+ s = tmpstr; /* points to current position in tmpstr[] */
- LASSERT (lbsi->lbsi_idx >= 0 && lbsi->lbsi_idx < LNET_NRBPOOLS);
+ s += snprintf(s, tmpstr + tmpsiz - s,
+ "%5s %5s %7s %7s\n",
+ "pages", "count", "credits", "min");
+ LASSERT (tmpstr + tmpsiz - s > 0);
LNET_LOCK();
- rbp = &the_lnet.ln_rtrpools[lbsi->lbsi_idx];
+ for (idx = 0; idx < LNET_NRBPOOLS; idx++) {
+ lnet_rtrbufpool_t *rbp = &the_lnet.ln_rtrpools[idx];
+
+ int npages = rbp->rbp_npages;
+ int nbuf = rbp->rbp_nbuffers;
+ int cr = rbp->rbp_credits;
+ int mincr = rbp->rbp_mincredits;
- npages = rbp->rbp_npages;
- nbuf = rbp->rbp_nbuffers;
- cr = rbp->rbp_credits;
- mincr = rbp->rbp_mincredits;
+ s += snprintf(s, tmpstr + tmpsiz - s,
+ "%5d %5d %7d %7d\n",
+ npages, nbuf, cr, mincr);
+ LASSERT (tmpstr + tmpsiz - s > 0);
+ }
LNET_UNLOCK();
- seq_printf(s, "%5d %5d %7d %7d\n",
- npages, nbuf, cr, mincr);
- return 0;
-}
+ len = s - tmpstr;
-static struct seq_operations lnet_buffer_sops = {
- .start = lnet_buffer_seq_start,
- .stop = lnet_buffer_seq_stop,
- .next = lnet_buffer_seq_next,
- .show = lnet_buffer_seq_show,
-};
-
-static int
-lnet_buffer_seq_open(struct inode *inode, struct file *file)
-{
- struct proc_dir_entry *dp = PDE(inode);
- struct seq_file *sf;
- int rc;
-
- rc = seq_open(file, &lnet_buffer_sops);
- if (rc == 0) {
- sf = file->private_data;
- sf->private = dp->data;
- }
+ if (pos >= min_t(int, len, strlen(tmpstr)))
+ rc = 0;
+ else
+ rc = cfs_trace_copyout_string(buffer, nob,
+ tmpstr + pos, NULL);
+ LIBCFS_FREE(tmpstr, tmpsiz);
return rc;
}
-static struct file_operations lnet_buffers_fops = {
- .owner = THIS_MODULE,
- .open = lnet_buffer_seq_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = seq_release,
-};
+DECLARE_PROC_HANDLER(proc_lnet_buffers);
-typedef struct {
- lnet_ni_t *lnsi_ni;
- loff_t lnsi_off;
-} lnet_ni_seq_iterator_t;
-
-int
-lnet_ni_seq_seek (lnet_ni_seq_iterator_t *lnsi, loff_t off)
+int LL_PROC_PROTO(proc_lnet_nis)
{
- struct list_head *n;
- loff_t here;
- int rc;
+ int rc = 0;
+ char *tmpstr;
+ char *s;
+ const int tmpsiz = 256;
+ int len;
- if (off == 0) {
- lnsi->lnsi_ni = NULL;
- lnsi->lnsi_off = 0;
- return 0;
- }
+ DECLARE_LL_PROC_PPOS_DECL;
- LNET_LOCK();
+ LASSERT (!write);
- if (lnsi->lnsi_ni == NULL ||
- lnsi->lnsi_off > off) {
- /* search from start */
- n = NULL;
- here = 1;
- } else {
- /* continue search */
- n = &lnsi->lnsi_ni->ni_list;
- here = lnsi->lnsi_off;
- }
-
- lnsi->lnsi_off = off;
+ if (*lenp == 0)
+ return 0;
- if (n == NULL)
- n = the_lnet.ln_nis.next;
+ LIBCFS_ALLOC(tmpstr, tmpsiz);
+ if (tmpstr == NULL)
+ return -ENOMEM;
- while (n != &the_lnet.ln_nis) {
- if (here == off) {
- lnsi->lnsi_ni = list_entry(n, lnet_ni_t, ni_list);
- rc = 0;
- goto out;
- }
- here++;
- n = n->next;
- }
+ s = tmpstr; /* points to current position in tmpstr[] */
- lnsi->lnsi_ni = NULL;
- rc = -ENOENT;
- out:
- LNET_UNLOCK();
- return rc;
-}
+ if (*ppos == 0) {
+ s += snprintf(s, tmpstr + tmpsiz - s,
+ "%-24s %6s %5s %4s %4s %4s %5s %5s %5s\n",
+ "nid", "status", "alive", "refs", "peer",
+ "rtr", "max", "tx", "min");
+ LASSERT (tmpstr + tmpsiz - s > 0);
+ } else {
+ cfs_list_t *n;
+ lnet_ni_t *ni = NULL;
+ int skip = *ppos - 1;
-static void *
-lnet_ni_seq_start (struct seq_file *s, loff_t *pos)
-{
- lnet_ni_seq_iterator_t *lnsi;
- int rc;
+ LNET_LOCK();
- LIBCFS_ALLOC(lnsi, sizeof(*lnsi));
- if (lnsi == NULL)
- return NULL;
+ n = the_lnet.ln_nis.next;
- lnsi->lnsi_ni = NULL;
- rc = lnet_ni_seq_seek(lnsi, *pos);
- if (rc == 0)
- return lnsi;
+ while (n != &the_lnet.ln_nis) {
+ lnet_ni_t *a_ni = cfs_list_entry(n, lnet_ni_t, ni_list);
- LIBCFS_FREE(lnsi, sizeof(*lnsi));
- return NULL;
-}
+ if (skip == 0) {
+ ni = a_ni;
+ break;
+ }
-static void
-lnet_ni_seq_stop (struct seq_file *s, void *iter)
-{
- lnet_ni_seq_iterator_t *lnsi = iter;
+ skip--;
+ n = n->next;
+ }
- if (lnsi != NULL)
- LIBCFS_FREE(lnsi, sizeof(*lnsi));
-}
+ if (ni != NULL) {
+ cfs_time_t now = cfs_time_current();
+ int last_alive = -1;
+ int maxtxcr = ni->ni_maxtxcredits;
+ int txcr = ni->ni_txcredits;
+ int mintxcr = ni->ni_mintxcredits;
+ int npeertxcr = ni->ni_peertxcredits;
+ int npeerrtrcr = ni->ni_peerrtrcredits;
+ lnet_nid_t nid = ni->ni_nid;
+ int nref = ni->ni_refcount;
+ char *stat;
+
+ if (the_lnet.ln_routing)
+ last_alive = cfs_duration_sec(cfs_time_sub(now,
+ ni->ni_last_alive));
+ if (ni->ni_lnd->lnd_type == LOLND) /* @lo forever alive */
+ last_alive = 0;
+
+ LASSERT (ni->ni_status != NULL);
+ stat = (ni->ni_status->ns_status == LNET_NI_STATUS_UP) ?
+ "up" : "down";
+
+ s += snprintf(s, tmpstr + tmpsiz - s,
+ "%-24s %6s %5d %4d %4d %4d %5d %5d %5d\n",
+ libcfs_nid2str(nid), stat, last_alive, nref,
+ npeertxcr, npeerrtrcr, maxtxcr,
+ txcr, mintxcr);
+ LASSERT (tmpstr + tmpsiz - s > 0);
+ }
-static void *
-lnet_ni_seq_next (struct seq_file *s, void *iter, loff_t *pos)
-{
- lnet_ni_seq_iterator_t *lnsi = iter;
- int rc;
- loff_t next = *pos + 1;
-
- rc = lnet_ni_seq_seek(lnsi, next);
- if (rc != 0) {
- LIBCFS_FREE(lnsi, sizeof(*lnsi));
- return NULL;
+ LNET_UNLOCK();
}
- *pos = next;
- return lnsi;
-}
+ len = s - tmpstr; /* how many bytes was written */
-static int
-lnet_ni_seq_show (struct seq_file *s, void *iter)
-{
- lnet_ni_seq_iterator_t *lnsi = iter;
- lnet_ni_t *ni;
- int maxtxcr;
- int txcr;
- int mintxcr;
- int npeertxcr;
- lnet_nid_t nid;
- int nref;
-
- if (lnsi->lnsi_off == 0) {
- seq_printf(s, "%-24s %4s %4s %5s %5s %5s\n",
- "nid", "refs", "peer", "max", "tx", "min");
- return 0;
+ 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
+ *ppos += 1;
}
- LASSERT (lnsi->lnsi_ni != NULL);
+ LIBCFS_FREE(tmpstr, tmpsiz);
- LNET_LOCK();
-
- ni = lnsi->lnsi_ni;
-
- maxtxcr = ni->ni_maxtxcredits;
- txcr = ni->ni_txcredits;
- mintxcr = ni->ni_mintxcredits;
- npeertxcr = ni->ni_peertxcredits;
- nid = ni->ni_nid;
- nref = ni->ni_refcount;
-
- LNET_UNLOCK();
+ if (rc == 0)
+ *lenp = len;
- seq_printf(s, "%-24s %4d %4d %5d %5d %5d\n",
- libcfs_nid2str(nid), nref,
- npeertxcr, maxtxcr, txcr, mintxcr);
- return 0;
+ return rc;
}
-static struct seq_operations lnet_ni_sops = {
- .start = lnet_ni_seq_start,
- .stop = lnet_ni_seq_stop,
- .next = lnet_ni_seq_next,
- .show = lnet_ni_seq_show,
+static cfs_sysctl_table_t lnet_table[] = {
+ /*
+ * NB No .strategy entries have been provided since sysctl(8) prefers
+ * to go via /proc for portability.
+ */
+ {
+ INIT_CTL_NAME(PSDEV_LNET_STATS)
+ .procname = "stats",
+ .mode = 0644,
+ .proc_handler = &proc_lnet_stats,
+ },
+ {
+ INIT_CTL_NAME(PSDEV_LNET_ROUTES)
+ .procname = "routes",
+ .mode = 0444,
+ .proc_handler = &proc_lnet_routes,
+ },
+ {
+ INIT_CTL_NAME(PSDEV_LNET_ROUTERS)
+ .procname = "routers",
+ .mode = 0444,
+ .proc_handler = &proc_lnet_routers,
+ },
+ {
+ INIT_CTL_NAME(PSDEV_LNET_PEERS)
+ .procname = "peers",
+ .mode = 0444,
+ .proc_handler = &proc_lnet_peers,
+ },
+ {
+ INIT_CTL_NAME(PSDEV_LNET_PEERS)
+ .procname = "buffers",
+ .mode = 0444,
+ .proc_handler = &proc_lnet_buffers,
+ },
+ {
+ INIT_CTL_NAME(PSDEV_LNET_NIS)
+ .procname = "nis",
+ .mode = 0444,
+ .proc_handler = &proc_lnet_nis,
+ },
+ {
+ INIT_CTL_NAME(0)
+ }
};
-static int
-lnet_ni_seq_open(struct inode *inode, struct file *file)
-{
- struct proc_dir_entry *dp = PDE(inode);
- struct seq_file *sf;
- int rc;
-
- rc = seq_open(file, &lnet_ni_sops);
- if (rc == 0) {
- sf = file->private_data;
- sf->private = dp->data;
+static cfs_sysctl_table_t top_table[] = {
+ {
+ INIT_CTL_NAME(CTL_LNET)
+ .procname = "lnet",
+ .mode = 0555,
+ .data = NULL,
+ .maxlen = 0,
+ .child = lnet_table,
+ },
+ {
+ INIT_CTL_NAME(0)
}
-
- return rc;
-}
-
-static struct file_operations lnet_ni_fops = {
- .owner = THIS_MODULE,
- .open = lnet_ni_seq_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = seq_release,
};
void
lnet_proc_init(void)
{
- struct proc_dir_entry *pde;
-
- /* Initialize LNET_PROC_STATS */
- pde = create_proc_entry (LNET_PROC_STATS, 0644, NULL);
- if (pde == NULL) {
- CERROR("couldn't create proc entry %s\n", LNET_PROC_STATS);
- return;
- }
-
- pde->data = NULL;
- pde->read_proc = lnet_router_proc_stats_read;
- pde->write_proc = lnet_router_proc_stats_write;
-
- /* Initialize LNET_PROC_ROUTES */
- pde = create_proc_entry (LNET_PROC_ROUTES, 0444, NULL);
- if (pde == NULL) {
- CERROR("couldn't create proc entry %s\n", LNET_PROC_ROUTES);
- return;
- }
-
- pde->proc_fops = &lnet_routes_fops;
- pde->data = NULL;
-
- /* Initialize LNET_PROC_ROUTERS */
- pde = create_proc_entry (LNET_PROC_ROUTERS, 0444, NULL);
- if (pde == NULL) {
- CERROR("couldn't create proc entry %s\n", LNET_PROC_ROUTERS);
- return;
- }
-
- pde->proc_fops = &lnet_routers_fops;
- pde->data = NULL;
-
- /* Initialize LNET_PROC_PEERS */
- pde = create_proc_entry (LNET_PROC_PEERS, 0444, NULL);
- if (pde == NULL) {
- CERROR("couldn't create proc entry %s\n", LNET_PROC_PEERS);
- return;
- }
-
- pde->proc_fops = &lnet_peer_fops;
- pde->data = NULL;
-
- /* Initialize LNET_PROC_BUFFERS */
- pde = create_proc_entry (LNET_PROC_BUFFERS, 0444, NULL);
- if (pde == NULL) {
- CERROR("couldn't create proc entry %s\n", LNET_PROC_BUFFERS);
- return;
- }
-
- pde->proc_fops = &lnet_buffers_fops;
- pde->data = NULL;
-
- /* Initialize LNET_PROC_NIS */
- pde = create_proc_entry (LNET_PROC_NIS, 0444, NULL);
- if (pde == NULL) {
- CERROR("couldn't create proc entry %s\n", LNET_PROC_NIS);
- return;
- }
-
- pde->proc_fops = &lnet_ni_fops;
- pde->data = NULL;
+#ifdef CONFIG_SYSCTL
+ if (lnet_table_header == NULL)
+ lnet_table_header = cfs_register_sysctl_table(top_table, 0);
+#endif
}
void
lnet_proc_fini(void)
{
- remove_proc_entry(LNET_PROC_STATS, 0);
- remove_proc_entry(LNET_PROC_ROUTES, 0);
- remove_proc_entry(LNET_PROC_ROUTERS, 0);
- remove_proc_entry(LNET_PROC_PEERS, 0);
- remove_proc_entry(LNET_PROC_BUFFERS, 0);
- remove_proc_entry(LNET_PROC_NIS, 0);
+#ifdef CONFIG_SYSCTL
+ if (lnet_table_header != NULL)
+ cfs_unregister_sysctl_table(lnet_table_header);
+
+ lnet_table_header = NULL;
+#endif
}
#else