1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2002 Cluster File Systems, Inc.
6 * This file is part of Portals
7 * http://sourceforge.net/projects/sandiaportals/
9 * Portals is free software; you can redistribute it and/or
10 * modify it under the terms of version 2 of the GNU General Public
11 * License as published by the Free Software Foundation.
13 * Portals is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with Portals; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #define KPR_PROC_ROUTER "sys/portals/router"
27 #define KPR_PROC_ROUTES "sys/portals/routes"
29 /* Used for multi-page route list book keeping */
30 struct proc_route_data {
31 struct list_head *curr;
32 unsigned int generation;
34 } kpr_read_routes_data;
36 /* nal2name support re-used from utils/portals.c */
49 static struct name2num *name2num_lookup_num(struct name2num *table, int num)
51 while (table->name != NULL)
52 if (num == table->num)
59 static char *nal2name(int nal)
61 struct name2num *e = name2num_lookup_num(nalnames, nal);
62 return ((e == NULL) ? "???" : e->name);
66 static int kpr_proc_router_read(char *page, char **start, off_t off,
67 int count, int *eof, void *data)
69 unsigned long long bytes = kpr_fwd_bytes;
70 unsigned long packets = kpr_fwd_packets;
71 unsigned long errors = kpr_fwd_errors;
72 unsigned int qdepth = atomic_read (&kpr_queue_depth);
79 len = sprintf(page, "%Ld %ld %ld %d\n", bytes, packets, errors, qdepth);
85 static int kpr_proc_router_write(struct file *file, const char *ubuffer,
86 unsigned long count, void *data)
88 /* Ignore what we've been asked to write, and just zero the stats */
96 static int kpr_proc_routes_read(char *page, char **start, off_t off,
97 int count, int *eof, void *data)
99 struct proc_route_data *prd = data;
100 kpr_route_entry_t *re;
101 kpr_gateway_entry_t *ge;
109 if (prd->curr == NULL) {
113 /* First pass, initialize our private data */
114 prd->curr = kpr_routes.next;
115 prd->generation = kpr_routes_generation;
118 /* Abort route list generation change */
119 if (prd->generation != kpr_routes_generation) {
121 return sprintf(page, "\nError: Routes Changed\n");
124 /* All the routes have been walked */
125 if (prd->curr == &kpr_routes) {
131 read_lock(&kpr_rwlock);
132 *start = page + prd->skip;
133 user_len = -prd->skip;
135 for (; prd->curr != &kpr_routes; prd->curr = prd->curr->next) {
136 re = list_entry(prd->curr, kpr_route_entry_t, kpre_list);
137 ge = re->kpre_gateway;
139 line_len = sprintf(page + chunk_len,
140 "%12s "LPX64" : "LPX64" - "LPX64", %s\n",
141 nal2name(ge->kpge_nalid), ge->kpge_nid,
142 re->kpre_lo_nid, re->kpre_hi_nid,
143 ge->kpge_alive ? "up" : "down");
144 chunk_len += line_len;
145 user_len += line_len;
147 /* The route table will exceed one page */
148 if ((chunk_len > (PAGE_SIZE - 80)) || (user_len > count)) {
149 prd->curr = prd->curr->next;
156 /* Caller received only a portion of the last entry, the
157 * remaining will be delivered in the next page if asked for.
159 if (user_len > count) {
160 prd->curr = prd->curr->prev;
161 prd->skip = line_len - (user_len - count);
162 read_unlock(&kpr_rwlock);
166 /* Not enough data to entirely satify callers request */
168 read_unlock(&kpr_rwlock);
172 static int kpr_proc_routes_write(struct file *file, const char *ubuffer,
173 unsigned long count, void *data)
175 /* no-op; lctl should be used to adjust the routes */
179 void kpr_proc_init(void)
181 struct proc_dir_entry *router_entry;
182 struct proc_dir_entry *routes_entry;
184 /* Initialize KPR_PROC_ROUTER */
185 router_entry = create_proc_entry (KPR_PROC_ROUTER,
186 S_IFREG | S_IRUGO | S_IWUSR, NULL);
188 if (router_entry == NULL) {
189 CERROR("couldn't create proc entry %s\n", KPR_PROC_ROUTER);
193 router_entry->data = NULL;
194 router_entry->read_proc = kpr_proc_router_read;
195 router_entry->write_proc = kpr_proc_router_write;
197 /* Initialize KPR_PROC_ROUTES */
198 routes_entry = create_proc_entry (KPR_PROC_ROUTES,
199 S_IFREG | S_IRUGO | S_IWUSR, NULL);
201 if (routes_entry == NULL) {
202 CERROR("couldn't create proc entry %s\n", KPR_PROC_ROUTES);
206 kpr_read_routes_data.curr = NULL;
207 kpr_read_routes_data.generation = 0;
208 kpr_read_routes_data.skip = 0;
210 routes_entry->data = &kpr_read_routes_data;
211 routes_entry->read_proc = kpr_proc_routes_read;
212 routes_entry->write_proc = kpr_proc_routes_write;
215 void kpr_proc_fini(void)
217 remove_proc_entry(KPR_PROC_ROUTER, 0);
218 remove_proc_entry(KPR_PROC_ROUTES, 0);