]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/contrib/rdma/krping/krping_dev.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / sys / contrib / rdma / krping / krping_dev.c
1 /*
2  * This code lifted from:
3  *      Simple `echo' pseudo-device KLD
4  *      Murray Stokely
5  *      Converted to 5.X by Søren (Xride) Straarup
6  */
7
8 /*
9  * /bin/echo "server,port=9999,addr=192.168.69.142,validate" > /dev/krping
10  * /bin/echo "client,port=9999,addr=192.168.69.142,validate" > /dev/krping
11  */
12
13 #include <sys/cdefs.h>
14 __FBSDID("$FreeBSD$");
15
16 #include <sys/types.h>
17 #include <sys/module.h>
18 #include <sys/systm.h>  /* uprintf */
19 #include <sys/errno.h>
20 #include <sys/param.h>  /* defines used in kernel.h */
21 #include <sys/kernel.h> /* types used in module initialization */
22 #include <sys/conf.h>   /* cdevsw struct */
23 #include <sys/uio.h>    /* uio struct */
24 #include <sys/malloc.h>
25 #include <sys/proc.h>
26 #include <sys/sysctl.h>
27 #include <machine/stdarg.h>
28
29 #include "krping.h"
30
31 #define BUFFERSIZE 512
32
33 SYSCTL_NODE(_dev, OID_AUTO, krping, CTLFLAG_RW, 0, "kernel rping module");
34
35 int krping_debug = 0;
36 SYSCTL_INT(_dev_krping, OID_AUTO, debug, CTLFLAG_RW, &krping_debug, 0 , "");
37
38 /* Function prototypes */
39 static d_open_t      krping_open;
40 static d_close_t     krping_close;
41 static d_read_t      krping_read;
42 static d_write_t     krping_write;
43
44 /* Character device entry points */
45 static struct cdevsw krping_cdevsw = {
46         .d_version = D_VERSION,
47         .d_open = krping_open,
48         .d_close = krping_close,
49         .d_read = krping_read,
50         .d_write = krping_write,
51         .d_name = "krping",
52 };
53
54 typedef struct s_krping {
55         char msg[BUFFERSIZE];
56         int len;
57 } krping_t;
58
59 struct stats_list_entry {
60         STAILQ_ENTRY(stats_list_entry) link;
61         struct krping_stats *stats;
62 };
63 STAILQ_HEAD(stats_list, stats_list_entry);
64
65 /* vars */
66 static struct cdev *krping_dev;
67
68 static int
69 krping_loader(struct module *m, int what, void *arg)
70 {
71         int err = 0;
72
73         switch (what) {
74         case MOD_LOAD:                /* kldload */
75                 krping_init();
76                 krping_dev = make_dev(&krping_cdevsw, 0, UID_ROOT, GID_WHEEL,
77                                         0600, "krping");
78                 printf("Krping device loaded.\n");
79                 break;
80         case MOD_UNLOAD:
81                 destroy_dev(krping_dev);
82                 printf("Krping device unloaded.\n");
83                 break;
84         default:
85                 err = EOPNOTSUPP;
86                 break;
87         }
88
89         return (err);
90 }
91
92 static int
93 krping_open(struct cdev *dev, int oflags, int devtype, struct thread *p)
94 {
95
96         return (0);
97 }
98
99 static int
100 krping_close(struct cdev *dev, int fflag, int devtype, struct thread *p)
101 {
102
103         return 0;
104 }
105
106 static void
107 krping_copy_stats(struct krping_stats *stats, void *arg)
108 {
109         struct stats_list_entry *s;
110         struct stats_list *list = arg;
111
112         s = malloc(sizeof(*s), M_DEVBUF, M_NOWAIT | M_ZERO);
113         if (s == NULL)
114                 return;
115         if (stats != NULL) {
116                 s->stats = malloc(sizeof(*stats), M_DEVBUF, M_NOWAIT | M_ZERO);
117                 if (s->stats == NULL) {
118                         free(s, M_DEVBUF);
119                         return;
120                 }
121                 *s->stats = *stats;
122         }
123         STAILQ_INSERT_TAIL(list, s, link);
124 }
125
126 static int
127 krping_read(struct cdev *dev, struct uio *uio, int ioflag)
128 {
129         int num = 1;
130         struct stats_list list;
131         struct stats_list_entry *e;
132
133         STAILQ_INIT(&list);
134         krping_walk_cb_list(krping_copy_stats, &list);
135
136         if (STAILQ_EMPTY(&list))
137                 return (0);
138
139         uprintf("krping: %4s %10s %10s %10s %10s %10s %10s %10s %10s %10s\n",
140             "num", "device", "snd bytes", "snd msgs", "rcv bytes", "rcv msgs",
141             "wr bytes", "wr msgs", "rd bytes", "rd msgs");
142
143         while (!STAILQ_EMPTY(&list)) {
144                 e = STAILQ_FIRST(&list);
145                 STAILQ_REMOVE_HEAD(&list, link);
146                 if (e->stats == NULL)
147                         uprintf("krping: %d listen\n", num);
148                 else {
149                         struct krping_stats *stats = e->stats;
150
151                         uprintf("krping: %4d %10s %10llu %10llu %10llu %10llu "
152                             "%10llu %10llu %10llu %10llu\n", num, stats->name,
153                             stats->send_bytes, stats->send_msgs,
154                             stats->recv_bytes, stats->recv_msgs,
155                             stats->write_bytes, stats->write_msgs,
156                             stats->read_bytes, stats->read_msgs);
157                         free(stats, M_DEVBUF);
158                 }
159                 num++;
160                 free(e, M_DEVBUF);
161         }
162
163         return (0);
164 }
165
166 static int
167 krping_write(struct cdev *dev, struct uio *uio, int ioflag)
168 {
169         int err = 0;
170         int amt;
171         int remain = BUFFERSIZE;
172         char *cp;
173         krping_t *krpingmsg;
174
175         krpingmsg = malloc(sizeof *krpingmsg, M_DEVBUF, M_WAITOK|M_ZERO);
176         if (!krpingmsg) {
177                 uprintf("Could not malloc mem!\n");
178                 return ENOMEM;
179         }
180
181         cp = krpingmsg->msg;
182         while (uio->uio_resid) {
183                 amt = MIN(uio->uio_resid, remain);
184                 if (amt == 0)
185                         break;
186
187                 /* Copy the string in from user memory to kernel memory */
188                 err = uiomove(cp, amt, uio);
189                 if (err) {
190                         uprintf("Write failed: bad address!\n");
191                         return err;
192                 }
193                 cp += amt;
194                 remain -= amt;
195         }
196
197         if (uio->uio_resid != 0) {
198                 uprintf("Message too big. max size is %d!\n", BUFFERSIZE);
199                 return EMSGSIZE;
200         }
201
202         /* null terminate and remove the \n */
203         cp--;
204         *cp = 0;
205         krpingmsg->len = (unsigned long)(cp - krpingmsg->msg);
206         uprintf("krping: write string = |%s|\n", krpingmsg->msg);
207         err = krping_doit(krpingmsg->msg, curproc);
208         free(krpingmsg, M_DEVBUF);
209         return(err);
210 }
211
212 void
213 krping_printf(void *cookie, const char *fmt, ...)
214 {
215         va_list ap;
216
217         va_start(ap, fmt);
218         vtprintf(cookie, -1, fmt, ap);
219         va_end(ap);
220 }
221
222 int
223 krping_sigpending(void)
224 {
225
226         return (SIGPENDING(curthread));
227 }
228
229 DEV_MODULE(krping, krping_loader, NULL);
230 MODULE_DEPEND(krping, ibcore, 1, 1, 1);