Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/rdma/krping/krping_dev.c
48254 views
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/param.h> /* defines used in kernel.h and module.h */
18
#include <sys/module.h>
19
#include <sys/systm.h> /* uprintf */
20
#include <sys/errno.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/stdarg.h>
27
#include <sys/sysctl.h>
28
29
#include "krping.h"
30
31
#define BUFFERSIZE 512
32
33
SYSCTL_NODE(_dev, OID_AUTO, krping, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
34
"kernel rping module");
35
36
int krping_debug = 0;
37
SYSCTL_INT(_dev_krping, OID_AUTO, debug, CTLFLAG_RW, &krping_debug, 0 , "");
38
39
/* Function prototypes */
40
static d_open_t krping_open;
41
static d_close_t krping_close;
42
static d_read_t krping_read;
43
static d_write_t krping_write;
44
static d_purge_t krping_purge;
45
46
/* Character device entry points */
47
static struct cdevsw krping_cdevsw = {
48
.d_version = D_VERSION,
49
.d_open = krping_open,
50
.d_close = krping_close,
51
.d_read = krping_read,
52
.d_write = krping_write,
53
.d_purge = krping_purge,
54
.d_name = "krping",
55
};
56
57
typedef struct s_krping {
58
char msg[BUFFERSIZE];
59
int len;
60
} krping_t;
61
62
struct stats_list_entry {
63
STAILQ_ENTRY(stats_list_entry) link;
64
struct krping_stats *stats;
65
};
66
STAILQ_HEAD(stats_list, stats_list_entry);
67
68
/* vars */
69
static struct cdev *krping_dev;
70
71
static int
72
krping_loader(struct module *m, int what, void *arg)
73
{
74
int err = 0;
75
76
switch (what) {
77
case MOD_LOAD: /* kldload */
78
krping_dev = make_dev(&krping_cdevsw, 0, UID_ROOT, GID_WHEEL,
79
0600, "krping");
80
printf("Krping device loaded.\n");
81
break;
82
case MOD_UNLOAD:
83
destroy_dev(krping_dev);
84
printf("Krping device unloaded.\n");
85
break;
86
default:
87
err = EOPNOTSUPP;
88
break;
89
}
90
91
return (err);
92
}
93
94
static int
95
krping_open(struct cdev *dev, int oflags, int devtype, struct thread *p)
96
{
97
98
return (0);
99
}
100
101
static int
102
krping_close(struct cdev *dev, int fflag, int devtype, struct thread *p)
103
{
104
105
return 0;
106
}
107
108
static void
109
krping_copy_stats(struct krping_stats *stats, void *arg)
110
{
111
struct stats_list_entry *s;
112
struct stats_list *list = arg;
113
114
s = malloc(sizeof(*s), M_DEVBUF, M_NOWAIT | M_ZERO);
115
if (s == NULL)
116
return;
117
if (stats != NULL) {
118
s->stats = malloc(sizeof(*stats), M_DEVBUF, M_NOWAIT | M_ZERO);
119
if (s->stats == NULL) {
120
free(s, M_DEVBUF);
121
return;
122
}
123
*s->stats = *stats;
124
}
125
STAILQ_INSERT_TAIL(list, s, link);
126
}
127
128
static int
129
krping_read(struct cdev *dev, struct uio *uio, int ioflag)
130
{
131
int num = 1;
132
struct stats_list list;
133
struct stats_list_entry *e;
134
135
STAILQ_INIT(&list);
136
krping_walk_cb_list(krping_copy_stats, &list);
137
138
if (STAILQ_EMPTY(&list))
139
return (0);
140
141
uprintf("krping: %4s %10s %10s %10s %10s %10s %10s %10s %10s %10s\n",
142
"num", "device", "snd bytes", "snd msgs", "rcv bytes", "rcv msgs",
143
"wr bytes", "wr msgs", "rd bytes", "rd msgs");
144
145
while (!STAILQ_EMPTY(&list)) {
146
e = STAILQ_FIRST(&list);
147
STAILQ_REMOVE_HEAD(&list, link);
148
if (e->stats == NULL)
149
uprintf("krping: %d listen\n", num);
150
else {
151
struct krping_stats *stats = e->stats;
152
153
uprintf("krping: %4d %10s %10llu %10llu %10llu %10llu "
154
"%10llu %10llu %10llu %10llu\n", num, stats->name,
155
stats->send_bytes, stats->send_msgs,
156
stats->recv_bytes, stats->recv_msgs,
157
stats->write_bytes, stats->write_msgs,
158
stats->read_bytes, stats->read_msgs);
159
free(stats, M_DEVBUF);
160
}
161
num++;
162
free(e, M_DEVBUF);
163
}
164
165
return (0);
166
}
167
168
static int
169
krping_write(struct cdev *dev, struct uio *uio, int ioflag)
170
{
171
int err = 0;
172
int amt;
173
int remain = BUFFERSIZE;
174
char *cp;
175
krping_t *krpingmsg;
176
177
krpingmsg = malloc(sizeof *krpingmsg, M_DEVBUF, M_WAITOK | M_ZERO);
178
cp = krpingmsg->msg;
179
while (uio->uio_resid) {
180
amt = MIN(uio->uio_resid, remain);
181
if (amt == 0)
182
break;
183
184
/* Copy the string in from user memory to kernel memory */
185
err = uiomove(cp, amt, uio);
186
if (err) {
187
uprintf("Write failed: bad address!\n");
188
goto done;
189
}
190
cp += amt;
191
remain -= amt;
192
}
193
194
if (uio->uio_resid != 0) {
195
uprintf("Message too big. max size is %d!\n", BUFFERSIZE);
196
err = EMSGSIZE;
197
goto done;
198
}
199
200
/* null terminate and remove the \n */
201
cp--;
202
*cp = 0;
203
krpingmsg->len = (unsigned long)(cp - krpingmsg->msg);
204
uprintf("krping: write string = |%s|\n", krpingmsg->msg);
205
err = krping_doit(krpingmsg->msg);
206
done:
207
free(krpingmsg, M_DEVBUF);
208
return(err);
209
}
210
211
static void
212
krping_purge(struct cdev *dev __unused)
213
{
214
215
krping_cancel_all();
216
}
217
218
int
219
krping_sigpending(void)
220
{
221
222
return (SIGPENDING(curthread));
223
}
224
225
DEV_MODULE(krping, krping_loader, NULL);
226
MODULE_DEPEND(krping, ibcore, 1, 1, 1);
227
228