Path: blob/main/sys/contrib/rdma/krping/krping_dev.c
48254 views
/*1* This code lifted from:2* Simple `echo' pseudo-device KLD3* Murray Stokely4* Converted to 5.X by Søren (Xride) Straarup5*/67/*8* /bin/echo "server,port=9999,addr=192.168.69.142,validate" > /dev/krping9* /bin/echo "client,port=9999,addr=192.168.69.142,validate" > /dev/krping10*/1112#include <sys/cdefs.h>13__FBSDID("$FreeBSD$");1415#include <sys/types.h>16#include <sys/param.h> /* defines used in kernel.h and module.h */17#include <sys/module.h>18#include <sys/systm.h> /* uprintf */19#include <sys/errno.h>20#include <sys/kernel.h> /* types used in module initialization */21#include <sys/conf.h> /* cdevsw struct */22#include <sys/uio.h> /* uio struct */23#include <sys/malloc.h>24#include <sys/proc.h>25#include <sys/stdarg.h>26#include <sys/sysctl.h>2728#include "krping.h"2930#define BUFFERSIZE 5123132SYSCTL_NODE(_dev, OID_AUTO, krping, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,33"kernel rping module");3435int krping_debug = 0;36SYSCTL_INT(_dev_krping, OID_AUTO, debug, CTLFLAG_RW, &krping_debug, 0 , "");3738/* Function prototypes */39static d_open_t krping_open;40static d_close_t krping_close;41static d_read_t krping_read;42static d_write_t krping_write;43static d_purge_t krping_purge;4445/* Character device entry points */46static struct cdevsw krping_cdevsw = {47.d_version = D_VERSION,48.d_open = krping_open,49.d_close = krping_close,50.d_read = krping_read,51.d_write = krping_write,52.d_purge = krping_purge,53.d_name = "krping",54};5556typedef struct s_krping {57char msg[BUFFERSIZE];58int len;59} krping_t;6061struct stats_list_entry {62STAILQ_ENTRY(stats_list_entry) link;63struct krping_stats *stats;64};65STAILQ_HEAD(stats_list, stats_list_entry);6667/* vars */68static struct cdev *krping_dev;6970static int71krping_loader(struct module *m, int what, void *arg)72{73int err = 0;7475switch (what) {76case MOD_LOAD: /* kldload */77krping_dev = make_dev(&krping_cdevsw, 0, UID_ROOT, GID_WHEEL,780600, "krping");79printf("Krping device loaded.\n");80break;81case MOD_UNLOAD:82destroy_dev(krping_dev);83printf("Krping device unloaded.\n");84break;85default:86err = EOPNOTSUPP;87break;88}8990return (err);91}9293static int94krping_open(struct cdev *dev, int oflags, int devtype, struct thread *p)95{9697return (0);98}99100static int101krping_close(struct cdev *dev, int fflag, int devtype, struct thread *p)102{103104return 0;105}106107static void108krping_copy_stats(struct krping_stats *stats, void *arg)109{110struct stats_list_entry *s;111struct stats_list *list = arg;112113s = malloc(sizeof(*s), M_DEVBUF, M_NOWAIT | M_ZERO);114if (s == NULL)115return;116if (stats != NULL) {117s->stats = malloc(sizeof(*stats), M_DEVBUF, M_NOWAIT | M_ZERO);118if (s->stats == NULL) {119free(s, M_DEVBUF);120return;121}122*s->stats = *stats;123}124STAILQ_INSERT_TAIL(list, s, link);125}126127static int128krping_read(struct cdev *dev, struct uio *uio, int ioflag)129{130int num = 1;131struct stats_list list;132struct stats_list_entry *e;133134STAILQ_INIT(&list);135krping_walk_cb_list(krping_copy_stats, &list);136137if (STAILQ_EMPTY(&list))138return (0);139140uprintf("krping: %4s %10s %10s %10s %10s %10s %10s %10s %10s %10s\n",141"num", "device", "snd bytes", "snd msgs", "rcv bytes", "rcv msgs",142"wr bytes", "wr msgs", "rd bytes", "rd msgs");143144while (!STAILQ_EMPTY(&list)) {145e = STAILQ_FIRST(&list);146STAILQ_REMOVE_HEAD(&list, link);147if (e->stats == NULL)148uprintf("krping: %d listen\n", num);149else {150struct krping_stats *stats = e->stats;151152uprintf("krping: %4d %10s %10llu %10llu %10llu %10llu "153"%10llu %10llu %10llu %10llu\n", num, stats->name,154stats->send_bytes, stats->send_msgs,155stats->recv_bytes, stats->recv_msgs,156stats->write_bytes, stats->write_msgs,157stats->read_bytes, stats->read_msgs);158free(stats, M_DEVBUF);159}160num++;161free(e, M_DEVBUF);162}163164return (0);165}166167static int168krping_write(struct cdev *dev, struct uio *uio, int ioflag)169{170int err = 0;171int amt;172int remain = BUFFERSIZE;173char *cp;174krping_t *krpingmsg;175176krpingmsg = malloc(sizeof *krpingmsg, M_DEVBUF, M_WAITOK | M_ZERO);177cp = krpingmsg->msg;178while (uio->uio_resid) {179amt = MIN(uio->uio_resid, remain);180if (amt == 0)181break;182183/* Copy the string in from user memory to kernel memory */184err = uiomove(cp, amt, uio);185if (err) {186uprintf("Write failed: bad address!\n");187goto done;188}189cp += amt;190remain -= amt;191}192193if (uio->uio_resid != 0) {194uprintf("Message too big. max size is %d!\n", BUFFERSIZE);195err = EMSGSIZE;196goto done;197}198199/* null terminate and remove the \n */200cp--;201*cp = 0;202krpingmsg->len = (unsigned long)(cp - krpingmsg->msg);203uprintf("krping: write string = |%s|\n", krpingmsg->msg);204err = krping_doit(krpingmsg->msg);205done:206free(krpingmsg, M_DEVBUF);207return(err);208}209210static void211krping_purge(struct cdev *dev __unused)212{213214krping_cancel_all();215}216217int218krping_sigpending(void)219{220221return (SIGPENDING(curthread));222}223224DEV_MODULE(krping, krping_loader, NULL);225MODULE_DEPEND(krping, ibcore, 1, 1, 1);226227228