freebsd-src/sys/contrib/rdma/krping/krping_dev.c
Bjoern A. Zeeb df38ada293 modules: increase MAXMODNAME and provide backward compat
With various firmware files used by graphics and wireless drivers
we are exceeding the current 32 character module name (file path
in kldxref) length.
In order to overcome this issue bump it to the maximum path length
for the next version.
To be able to MFC provide backward compat support for another version
of the struct as the offsets for the second half change due to the
array size increase.

MAXMODNAME being defined to MAXPATHLEN needs param.h to be
included first.  With only 7 modules (or LinuxKPI module.h) not
doing that adjust them rather than including param.h in module.h [1].

Reported by:	Greg V (greg unrelenting.technology)
Sponsored by:	The FreeBSD Foundation
Suggested by:	imp [1]
MFC after:	10 days
Reviewed by:	imp (and others to different level)
Differential Revision:	https://reviews.freebsd.org/D32383
2021-12-09 18:09:53 +00:00

232 lines
4.9 KiB
C

/*
* This code lifted from:
* Simple `echo' pseudo-device KLD
* Murray Stokely
* Converted to 5.X by Søren (Xride) Straarup
*/
/*
* /bin/echo "server,port=9999,addr=192.168.69.142,validate" > /dev/krping
* /bin/echo "client,port=9999,addr=192.168.69.142,validate" > /dev/krping
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/param.h> /* defines used in kernel.h and module.h */
#include <sys/module.h>
#include <sys/systm.h> /* uprintf */
#include <sys/errno.h>
#include <sys/kernel.h> /* types used in module initialization */
#include <sys/conf.h> /* cdevsw struct */
#include <sys/uio.h> /* uio struct */
#include <sys/malloc.h>
#include <sys/proc.h>
#include <sys/sysctl.h>
#include <machine/stdarg.h>
#include "krping.h"
#define BUFFERSIZE 512
SYSCTL_NODE(_dev, OID_AUTO, krping, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
"kernel rping module");
int krping_debug = 0;
SYSCTL_INT(_dev_krping, OID_AUTO, debug, CTLFLAG_RW, &krping_debug, 0 , "");
/* Function prototypes */
static d_open_t krping_open;
static d_close_t krping_close;
static d_read_t krping_read;
static d_write_t krping_write;
static d_purge_t krping_purge;
/* Character device entry points */
static struct cdevsw krping_cdevsw = {
.d_version = D_VERSION,
.d_open = krping_open,
.d_close = krping_close,
.d_read = krping_read,
.d_write = krping_write,
.d_purge = krping_purge,
.d_name = "krping",
};
typedef struct s_krping {
char msg[BUFFERSIZE];
int len;
} krping_t;
struct stats_list_entry {
STAILQ_ENTRY(stats_list_entry) link;
struct krping_stats *stats;
};
STAILQ_HEAD(stats_list, stats_list_entry);
/* vars */
static struct cdev *krping_dev;
static int
krping_loader(struct module *m, int what, void *arg)
{
int err = 0;
switch (what) {
case MOD_LOAD: /* kldload */
krping_dev = make_dev(&krping_cdevsw, 0, UID_ROOT, GID_WHEEL,
0600, "krping");
printf("Krping device loaded.\n");
break;
case MOD_UNLOAD:
destroy_dev(krping_dev);
printf("Krping device unloaded.\n");
break;
default:
err = EOPNOTSUPP;
break;
}
return (err);
}
static int
krping_open(struct cdev *dev, int oflags, int devtype, struct thread *p)
{
return (0);
}
static int
krping_close(struct cdev *dev, int fflag, int devtype, struct thread *p)
{
return 0;
}
static void
krping_copy_stats(struct krping_stats *stats, void *arg)
{
struct stats_list_entry *s;
struct stats_list *list = arg;
s = malloc(sizeof(*s), M_DEVBUF, M_NOWAIT | M_ZERO);
if (s == NULL)
return;
if (stats != NULL) {
s->stats = malloc(sizeof(*stats), M_DEVBUF, M_NOWAIT | M_ZERO);
if (s->stats == NULL) {
free(s, M_DEVBUF);
return;
}
*s->stats = *stats;
}
STAILQ_INSERT_TAIL(list, s, link);
}
static int
krping_read(struct cdev *dev, struct uio *uio, int ioflag)
{
int num = 1;
struct stats_list list;
struct stats_list_entry *e;
STAILQ_INIT(&list);
krping_walk_cb_list(krping_copy_stats, &list);
if (STAILQ_EMPTY(&list))
return (0);
uprintf("krping: %4s %10s %10s %10s %10s %10s %10s %10s %10s %10s\n",
"num", "device", "snd bytes", "snd msgs", "rcv bytes", "rcv msgs",
"wr bytes", "wr msgs", "rd bytes", "rd msgs");
while (!STAILQ_EMPTY(&list)) {
e = STAILQ_FIRST(&list);
STAILQ_REMOVE_HEAD(&list, link);
if (e->stats == NULL)
uprintf("krping: %d listen\n", num);
else {
struct krping_stats *stats = e->stats;
uprintf("krping: %4d %10s %10llu %10llu %10llu %10llu "
"%10llu %10llu %10llu %10llu\n", num, stats->name,
stats->send_bytes, stats->send_msgs,
stats->recv_bytes, stats->recv_msgs,
stats->write_bytes, stats->write_msgs,
stats->read_bytes, stats->read_msgs);
free(stats, M_DEVBUF);
}
num++;
free(e, M_DEVBUF);
}
return (0);
}
static int
krping_write(struct cdev *dev, struct uio *uio, int ioflag)
{
int err = 0;
int amt;
int remain = BUFFERSIZE;
char *cp;
krping_t *krpingmsg;
krpingmsg = malloc(sizeof *krpingmsg, M_DEVBUF, M_WAITOK|M_ZERO);
if (!krpingmsg) {
uprintf("Could not malloc mem!\n");
return ENOMEM;
}
cp = krpingmsg->msg;
while (uio->uio_resid) {
amt = MIN(uio->uio_resid, remain);
if (amt == 0)
break;
/* Copy the string in from user memory to kernel memory */
err = uiomove(cp, amt, uio);
if (err) {
uprintf("Write failed: bad address!\n");
goto done;
}
cp += amt;
remain -= amt;
}
if (uio->uio_resid != 0) {
uprintf("Message too big. max size is %d!\n", BUFFERSIZE);
err = EMSGSIZE;
goto done;
}
/* null terminate and remove the \n */
cp--;
*cp = 0;
krpingmsg->len = (unsigned long)(cp - krpingmsg->msg);
uprintf("krping: write string = |%s|\n", krpingmsg->msg);
err = krping_doit(krpingmsg->msg);
done:
free(krpingmsg, M_DEVBUF);
return(err);
}
static void
krping_purge(struct cdev *dev __unused)
{
krping_cancel_all();
}
int
krping_sigpending(void)
{
return (SIGPENDING(curthread));
}
DEV_MODULE(krping, krping_loader, NULL);
MODULE_DEPEND(krping, ibcore, 1, 1, 1);