summaryrefslogtreecommitdiffstats
path: root/share/examples
diff options
context:
space:
mode:
authorsjg <sjg@FreeBSD.org>2014-11-19 01:07:58 +0000
committersjg <sjg@FreeBSD.org>2014-11-19 01:07:58 +0000
commitb137080f19736ee33fede2e88bb54438604cf86b (patch)
tree377ac0ac449528621eb192cd245adadb5fd53668 /share/examples
parentab21a29eb607d4dfe389b965fbdee27558e791aa (diff)
parent4a8d07956d121238d006d34ffe7d6269744e8b1a (diff)
downloadFreeBSD-src-b137080f19736ee33fede2e88bb54438604cf86b.zip
FreeBSD-src-b137080f19736ee33fede2e88bb54438604cf86b.tar.gz
Merge from head@274682
Diffstat (limited to 'share/examples')
-rw-r--r--share/examples/autofs/driver/Makefile18
-rw-r--r--share/examples/autofs/driver/autodriver.c538
-rw-r--r--share/examples/autofs/driver/autotab7
-rwxr-xr-xshare/examples/bhyve/vmrun.sh36
-rw-r--r--share/examples/hwpmc/Makefile9
-rw-r--r--share/examples/hwpmc/README2
-rw-r--r--share/examples/hwpmc/overhead.c106
-rw-r--r--share/examples/kld/random_adaptor/random_adaptor_example.c54
8 files changed, 182 insertions, 588 deletions
diff --git a/share/examples/autofs/driver/Makefile b/share/examples/autofs/driver/Makefile
deleted file mode 100644
index 3e15883..0000000
--- a/share/examples/autofs/driver/Makefile
+++ /dev/null
@@ -1,18 +0,0 @@
-# $Id: Makefile,v 1.5 2004/09/08 08:27:12 bright Exp $
-# $FreeBSD$
-
-PROG= autodriver
-MAN=
-
-SRCS= autodriver.c
-WARNS?= 4
-CFLAGS+= -g
-BINDIR?= /sbin
-
-DPADD+= ${.OBJDIR}/../libautofs/libautofs.a
-#LDADD+= -lautofs
-LDADD+= ${.OBJDIR}/../libautofs/libautofs.a
-LDFLAGS+= -L${.OBJDIR}/../libautofs
-CFLAGS+= -I${.CURDIR}/../libautofs
-
-.include <bsd.prog.mk>
diff --git a/share/examples/autofs/driver/autodriver.c b/share/examples/autofs/driver/autodriver.c
deleted file mode 100644
index 69af0c5..0000000
--- a/share/examples/autofs/driver/autodriver.c
+++ /dev/null
@@ -1,538 +0,0 @@
-/*
- * Copyright (c) 2004 Alfred Perlstein <alfred@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id: autodriver.c,v 1.9 2004/09/08 08:12:21 bright Exp $
- * $FreeBSD$
- */
-#include <ctype.h>
-#include <err.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#include <sys/dirent.h>
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/mount.h>
-#include <sys/poll.h>
-#include <sys/stat.h>
-
-#include <libautofs.h>
-
-struct autoentry {
- char *ae_mnt; /* autofs mountpoint. */
- char *ae_path; /* path under mount. */
- char *ae_type; /* fs to be mounted type. */
- char *ae_opts; /* options passed to mount. */
- char *ae_rpath; /* remote path */
- char *ae_free; /* freeme! */
- char *ae_fullpath; /* full path to mount */
- int ae_line; /* line it came from in the conf. */
- int ae_indirect; /* is this an indirect mount? */
- int ae_direct; /* is this a direct mount? */
- int ae_browse; /* browseable? */
- struct autoentry *ae_next; /* next. */
-};
-
-struct autoentry *entries;
-const char *mount_prog = "mount";
-const char *fstype = "autofs";
-
-void *xmalloc(size_t);
-void *xcalloc(size_t number, size_t size);
-void parsetab(void);
-void populate_tab(void);
-void doreq(autoh_t, autoreq_t);
-void dotheneedful(autoh_t);
-void eventloop(void);
-int poll_handles(autoh_t *array, int cnt);
-int mount_indirect(struct autofs_userreq *req, struct autoentry *ent);
-int mount_direct(struct autofs_userreq *req, struct autoentry *ent);
-int mount_browse(struct autofs_userreq *req, struct autoentry *ent);
-
-#define DSTR(s) sizeof(s) - 1, s
-
-struct dirent dumbents[] = {
- {50, sizeof(struct dirent), DT_DIR, DSTR("one") },
- {51, sizeof(struct dirent), DT_DIR, DSTR(".") },
- {52, sizeof(struct dirent), DT_DIR, DSTR("..") },
- {50, sizeof(struct dirent), DT_DIR, DSTR("two") },
-};
-
-void *
-xmalloc(size_t size)
-{
- void *ret;
-
- ret = malloc(size);
- if (ret == NULL)
- err(1, "malloc %d", (int) size);
- return (ret);
-}
-
-void *
-xcalloc(size_t number, size_t size)
-{
- void *ret;
-
- ret = calloc(number, size);
- if (ret == NULL)
- err(1, "calloc %d %d", (int)number, (int)size);
- return (ret);
-}
-
-void
-parsetab(void)
-{
- FILE *fp;
- const char *tab;
- char *cp, *p, *line, *opt;
- size_t len;
- struct autoentry *ent;
- int i, lineno, x, gotopt;
- const char *expecting = "expecting 'direct', 'indirect' or 'browse'";
- const char *tabfiles[] = {
- "/etc/autotab", "/usr/local/etc/autotab", "./autotab", NULL
- };
-
- lineno = 0;
- for (i = 0; (tab = tabfiles[i]) != NULL; i++) {
- tab = tabfiles[i];
- fp = fopen(tab, "r");
- if (fp == NULL)
- warn("fopen %s", tab);
- if (fp != NULL)
- break;
- }
- if (fp == NULL) {
- err(1, "no config file available.");
- }
-
- fprintf(stderr, "using config file: %s\n", tab);
-
- while ((cp = fgetln(fp, &len)) != NULL) {
- lineno++;
- while (len > 0 && isspace(cp[len - 1]))
- len--;
- line = xmalloc(len + 1);
- bcopy(cp, line, len);
- line[len] = '\0';
- cp = line;
- if ((cp = strchr(line, '#')) != NULL)
- *cp = '\0';
- cp = line;
- while (isspace(*cp))
- cp++;
- if (*cp == '\0') {
- free(line);
- continue;
- }
- ent = xcalloc(1, sizeof(*ent));
- if ((p = strsep(&cp, " \t")) == NULL)
- goto bad;
- ent->ae_mnt = p;
- if ((p = strsep(&cp, " \t")) == NULL)
- goto bad;
- ent->ae_path = p;
- if ((p = strsep(&cp, " \t")) == NULL)
- goto bad;
- ent->ae_type = p;
- if ((p = strsep(&cp, " \t")) == NULL)
- goto bad;
- ent->ae_opts = p;
- if ((p = strsep(&cp, " \t")) == NULL)
- goto bad;
- ent->ae_rpath = p;
- if ((p = strsep(&cp, " \t")) == NULL)
- goto bad;
- gotopt = 0;
- opt = p;
- while ((p = strsep(&opt, ",")) != NULL) {
- if (strcmp(p, "indirect") == 0) {
- ent->ae_indirect = 1;
- gotopt = 1;
- } else if (strcmp(p, "direct") == 0) {
- ent->ae_direct = 1;
- gotopt = 1;
- } else if (strcmp(p, "browse") == 0) {
- ent->ae_browse = 1;
- gotopt = 1;
- } else {
- warnx("unreconized option '%s', %s",
- p, expecting);
- goto bad2;
- }
- }
- if (!gotopt) {
- warnx("no options specified %s", expecting);
- goto bad2;
- }
- if (ent->ae_direct && ent->ae_indirect) {
- warnx("direct and indirect are mutually exclusive");
- goto bad2;
-
- }
- x = asprintf(&ent->ae_fullpath, "%s/%s",
- ent->ae_mnt, ent->ae_path);
- if (x == -1)
- err(1, "asprintf");
-
- if (strlen(ent->ae_fullpath) + 1 > PATH_MAX) {
- warnx("Error in file %s, line %d, "
- "mountpath (%s) exceeds PATH_MAX (%d)",
- tab, lineno, ent->ae_fullpath, PATH_MAX);
- goto bad2;
- }
- ent->ae_line = lineno;
- ent->ae_free = line;
- ent->ae_next = entries;
- entries = ent;
- continue;
-bad:
- warnx("Parse error in file %s, line %d", tab, lineno);
-bad2:
- free(ent->ae_fullpath);
- free(line);
- free(ent);
- }
- if (ferror(fp))
- err(1, "error with file %s", tab);
-}
-
-void
-populate_tab(void)
-{
- struct autoentry *ent;
- char *path, *cmd;
- int error;
- autoh_t ah;
-
- path = cmd = NULL;
-
- for (ent = entries; ent != NULL; ent = ent->ae_next) {
- free(path);
- free(cmd);
- error = asprintf(&path, "%s/%s", ent->ae_mnt, ent->ae_path);
- if (error == -1)
- err(1, "asprintf");
- error = asprintf(&cmd, "mkdir -p %s", path);
- if (error == -1)
- err(1, "asprintf");
- error = system(cmd);
- if (error) {
- warn("system: %s", cmd);
- continue;
- }
- if (autoh_get(ent->ae_mnt, &ah)) {
- warn("autoh_get %s", path);
- continue;
- }
- error = autoh_togglepath(ah, AUTO_MOUNTER, getpid(), path);
- if (error) {
- err(1, "AUTO_MOUNTER %s", path);
- continue;
- }
- if (ent->ae_browse) {
- error = autoh_togglepath(ah, AUTO_BROWSE, getpid(),
- path);
- if (error)
- err(1, "AUTO_BROWSE %s", path);
- }
- if (ent->ae_direct) {
- error = autoh_togglepath(ah, AUTO_DIRECT, getpid(),
- path);
- if (error)
- err(1, "AUTO_DIRECT %s", path);
- }
- if (ent->ae_indirect) {
- error = autoh_togglepath(ah, AUTO_INDIRECT, getpid(),
- path);
- if (error)
- err(1, "AUTO_INDIRECT %s", path);
- }
- autoh_free(ah);
- }
- free(path);
- free(cmd);
-}
-
-/*
- * Process an autofs request, scan the list of entries in the config
- * looking for our node, if found mount it.
- */
-void
-doreq(autoh_t ah, autoreq_t req)
-{
- struct autoentry *ent;
- int error;
- int mcmp;
- int xid;
- const char *mnt;
-
- mnt = autoh_mp(ah);
-
- autoreq_seterrno(req, 0);
- for (ent = entries; ent != NULL; ent = ent->ae_next) {
- fprintf(stderr, "comparing {%s,%s} to {%s,%s}\n",
- mnt, ent->ae_mnt, autoreq_getpath(req), ent->ae_path);
- fprintf(stderr, "comparing {%d,%d} to {%d,%d}\n",
- (int)strlen(mnt),
- (int)strlen(ent->ae_mnt),
- (int)strlen(autoreq_getpath(req)),
- (int)strlen(ent->ae_path));
- autoreq_getxid(req, &xid);
- fprintf(stderr, "req xid %d\n", xid);
- if ((mcmp = strcmp(mnt, ent->ae_mnt)) != 0) {
- fprintf(stderr, "mcmp = %d\n", mcmp);
- continue;
- }
- if (mount_direct(req, ent))
- goto serve;
- if (mount_indirect(req, ent))
- goto serve;
- if (mount_browse(req, ent))
- goto serve;
- }
- fprintf(stderr, "no entry found...\n");
- autoreq_seterrno(req, ENOENT);
-serve:
- error = autoreq_serv(ah, req);
- if (error == -1) {
- warn("AUTOFS_CTL_SERVREQ");
- }
-}
-
-int
-mount_indirect(req, ent)
- struct autofs_userreq *req;
- struct autoentry *ent;
-{
- struct stat sb;
- char *path, *cmd;
- int error, x;
-
- if (ent->ae_indirect != 1) {
- fprintf(stderr, "not indirect.\n");
- return (0);
- }
- fprintf(stderr, "indirect mount...\n");
- /*
- * handle lookups, fake all stat(2) requests... this is bad,
- * but we're a driver so we don't care...
- * If we don't care about the type of request, then just return.
- */
- switch (autoreq_getop(req)) {
- case AUTOREQ_OP_LOOKUP:
- break;
- case AUTOREQ_OP_STAT:
- fprintf(stderr, "stat\n");
- return (1);
- default:
- fprintf(stderr, "unknown\n");
- return (0);
- }
- if (stat(ent->ae_fullpath, &sb))
- return (0);
- if (sb.st_ino != autoreq_getdirino(req)) {
- fprintf(stderr, "st_ino %d != dirino %d\n",
- (int)sb.st_ino, (int)autoreq_getdirino(req));
- return (0);
- }
- x = asprintf(&path, "%s/%s", ent->ae_fullpath, autoreq_getpath(req));
- if (x > PATH_MAX) {
- autoreq_seterrno(req, ENAMETOOLONG);
- return (1);
- }
- if (mkdir(path, 0555) == -1)
- warn("mkdir %s", path);
- error = asprintf(&cmd, "%s -t %s -o %s %s/%s %s", mount_prog,
- ent->ae_type, ent->ae_opts, ent->ae_rpath, autoreq_getpath(req), path);
- fprintf(stderr, "running:\n\t%s\n", cmd);
- error = system(cmd);
- fprintf(stderr, "error = %d\n", error);
- free(cmd);
- if (error) {
- if (rmdir(path) == -1)
- warn("rmdir %s", path);
- autoreq_seterrno(req, ENOENT);
- } else {
- if (stat(path, &sb) != -1)
- autoreq_setino(req, sb.st_ino);
- /* XXX !!! */
- /* req->au_flags = 1; */
- }
- free(path);
- return (1);
-}
-
-int
-mount_direct(req, ent)
- struct autofs_userreq *req;
- struct autoentry *ent;
-{
- struct stat sb;
- char *cmd;
- int error;
-
- if (ent->ae_direct != 1) {
- fprintf(stderr, "not direct.\n");
- return (0);
- }
- fprintf(stderr, "direct mount...\n");
- /*
- * handle lookups, fake all stat(2) requests... this is bad,
- * but we're a driver so we don't care...
- * If we don't care about the type of request, then just return.
- */
- switch (autoreq_getop(req)) {
- case AUTOREQ_OP_LOOKUP:
- break;
- case AUTOREQ_OP_STAT:
- return (1);
- default:
- return (0);
- }
- if (stat(ent->ae_fullpath, &sb))
- return (0);
- if (sb.st_ino != autoreq_getino(req))
- return (0);
- error = asprintf(&cmd, "%s -t %s -o %s %s %s", mount_prog,
- ent->ae_type, ent->ae_opts, ent->ae_rpath, ent->ae_fullpath);
- if (error == -1)
- err(1, "asprintf");
- fprintf(stderr, "running:\n\t%s\n", cmd);
- error = system(cmd);
- fprintf(stderr, "error = %d\n", error);
- free(cmd);
- if (error) {
- autoreq_seterrno(req, ENOENT);
- return (1);
- }
- /* XXX: fix ONLIST in kernel */
- /* req->au_flags = 1; */
- return (1);
-}
-
-int
-mount_browse(req, ent)
- struct autofs_userreq *req;
- struct autoentry *ent;
-{
- off_t off;
-
- if (ent->ae_browse != 1)
- return (0);
- if (autoreq_getop(req) != AUTOREQ_OP_READDIR)
- return (0);
- autoreq_getoffset(req, &off);
- if (off < sizeof(dumbents))
- autoreq_setaux(req, dumbents, sizeof(dumbents));
- fprintf(stderr, "mount_browse: offset %d, size %d\n",
- (int)off, (int)sizeof(dumbents));
- autoreq_seteof(req, 1);
- return (1);
-}
-
-/*
- * Ask the filesystem passed in if it has a pending request.
- * if so process them.
- */
-void
-dotheneedful(autoh_t ah)
-{
- int cnt, i;
- autoreq_t *reqs;
-
- if (autoreq_get(ah, &reqs, &cnt))
- err(1, "autoreq_get");
-
- for (i = 0; i < cnt; i++) {
- fprintf(stderr, "processing request for '%s' '%s'\n",
- autoh_mp(ah), autoreq_getpath(reqs[i]));
- doreq(ah, reqs[i]);
- }
- free(reqs);
-}
-
-int
-poll_handles(autoh_t *array, int cnt)
-{
- int i, saved_errno, x;
- static struct pollfd *pfd = NULL;
-
- pfd = reallocf(pfd, cnt * sizeof(*pfd));
- if (pfd == NULL)
- return (-1);
- for (i = 0; i < cnt; i++) {
- pfd[i].fd = autoh_fd(array[i]);
- pfd[i].events = POLLPRI;
- pfd[i].revents = 0;
- }
- fprintf(stderr, "start polling...\n");
- x = poll(pfd, cnt, 10000);
- saved_errno = errno;
- fprintf(stderr, "done polling...\n");
- errno = saved_errno;
- if (x == -1)
- return (-1);
- /* at least one fs is ready... */
- if (x > 0)
- return (0);
- return (0);
-}
-
-void
-eventloop(void)
-{
- autoh_t *array;
- int cnt, i;
-
- fprintf(stderr, "starting event loop...\n");
- for ( ;; ) {
- if (autoh_getall(&array, &cnt))
- err(1, "autoh_getall");
- if (poll_handles(array, cnt))
- err(1, "poll_handles");
- for (i = 0; i < cnt; i++) {
- dotheneedful(array[i]);
- }
- autoh_freeall(array);
- }
-}
-
-int
-main(int argc __unused, char **argv __unused)
-{
-
- if (getuid() != 0)
- errx(1, "autodriver needs to be run as root to work.");
- parsetab();
- populate_tab();
- eventloop();
- return (0);
-}
diff --git a/share/examples/autofs/driver/autotab b/share/examples/autofs/driver/autotab
deleted file mode 100644
index c56e072..0000000
--- a/share/examples/autofs/driver/autotab
+++ /dev/null
@@ -1,7 +0,0 @@
-# $Id: autotab,v 1.8 2004/09/08 08:12:21 bright Exp $
-# $FreeBSD$
-# autofs, directory, fstype, opts, path
-/auto share nfs ro,-R=1 big:/vol/share direct
-#/auto src nfs ro,-R=1 big:/vol/share/src indirect
-/auto src nfs ro,-R=1 big:/vol/share/src direct
-/auto browse nfs ro,-R=1 big:/vol/share/src browse,indirect
diff --git a/share/examples/bhyve/vmrun.sh b/share/examples/bhyve/vmrun.sh
index 33d0db9..93f3c94 100755
--- a/share/examples/bhyve/vmrun.sh
+++ b/share/examples/bhyve/vmrun.sh
@@ -152,7 +152,7 @@ make_and_check_diskdev()
{
local virtio_diskdev="$1"
# Create the virtio diskdev file if needed
- if [ ! -f ${virtio_diskdev} ]; then
+ if [ ! -e ${virtio_diskdev} ]; then
echo "virtio disk device file \"${virtio_diskdev}\" does not exist."
echo "Creating it ..."
truncate -s 8G ${virtio_diskdev} > /dev/null
@@ -173,13 +173,14 @@ echo "Launching virtual machine \"$vmname\" ..."
virtio_diskdev="$disk_dev0"
+${BHYVECTL} --vm=${vmname} --destroy > /dev/null 2>&1
+
while [ 1 ]; do
- ${BHYVECTL} --vm=${vmname} --destroy > /dev/null 2>&1
- file ${virtio_diskdev} | grep "boot sector" > /dev/null
+ file -s ${virtio_diskdev} | grep "boot sector" > /dev/null
rc=$?
if [ $rc -ne 0 ]; then
- file ${virtio_diskdev} | grep ": Unix Fast File sys" > /dev/null
+ file -s ${virtio_diskdev} | grep ": Unix Fast File sys" > /dev/null
rc=$?
fi
if [ $rc -ne 0 ]; then
@@ -195,7 +196,7 @@ while [ 1 ]; do
exit 1
fi
BOOTDISK=${isofile}
- installer_opt="-s 31:0,virtio-blk,${BOOTDISK}"
+ installer_opt="-s 31:0,ahci-cd,${BOOTDISK}"
else
BOOTDISK=${virtio_diskdev}
installer_opt=""
@@ -203,7 +204,8 @@ while [ 1 ]; do
${LOADER} -c ${console} -m ${memsize} -d ${BOOTDISK} ${loader_opt} \
${vmname}
- if [ $? -ne 0 ]; then
+ bhyve_exit=$?
+ if [ $bhyve_exit -ne 0 ]; then
break
fi
@@ -237,9 +239,27 @@ while [ 1 ]; do
-l com1,${console} \
${installer_opt} \
${vmname}
- if [ $? -ne 0 ]; then
+
+ bhyve_exit=$?
+ # bhyve returns the following status codes:
+ # 0 - VM has been reset
+ # 1 - VM has been powered off
+ # 2 - VM has been halted
+ # 3 - VM generated a triple fault
+ # all other non-zero status codes are errors
+ #
+ if [ $bhyve_exit -ne 0 ]; then
break
fi
done
-exit 99
+
+case $bhyve_exit in
+ 0|1|2)
+ # Cleanup /dev/vmm entry when bhyve did not exit
+ # due to an error.
+ ${BHYVECTL} --vm=${vmname} --destroy > /dev/null 2>&1
+ ;;
+esac
+
+exit $bhyve_exit
diff --git a/share/examples/hwpmc/Makefile b/share/examples/hwpmc/Makefile
new file mode 100644
index 0000000..a455fc6
--- /dev/null
+++ b/share/examples/hwpmc/Makefile
@@ -0,0 +1,9 @@
+# $FreeBSD$
+
+PROG= overhead
+LDFLAGS+= -lpmc
+MAN=
+
+install:
+
+.include <bsd.prog.mk>
diff --git a/share/examples/hwpmc/README b/share/examples/hwpmc/README
index 035e68d..6ad35b6 100644
--- a/share/examples/hwpmc/README
+++ b/share/examples/hwpmc/README
@@ -3,6 +3,4 @@
Examples illustrating the use of the hwpmc(4) driver and pmc(3)
library interface.
-While there is nothing here yet, the source code for pmccontrol(8)
-and pmcstat(8) could serve as examples.
diff --git a/share/examples/hwpmc/overhead.c b/share/examples/hwpmc/overhead.c
new file mode 100644
index 0000000..14834bd
--- /dev/null
+++ b/share/examples/hwpmc/overhead.c
@@ -0,0 +1,106 @@
+/*-
+ * Copyright (c) 2014, Neville-Neil Consulting
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ * Author: George V. Neville-Neil
+ *
+ */
+
+/*
+ * Calculate the time overhead of starting, stopping, and recording
+ * pmc counters.
+ *
+ * The only argument is a counter name, such as "instruction-retired"
+ * which is CPU dependent and can be found with pmmcontrol(8) using
+ * pmccontrol -L.
+ *
+ * The start, stop, read and write operations are timed using the
+ * rdtsc() macro which reads the Time Stamp Counter on the CPU.
+ */
+
+#include <stdio.h>
+#include <err.h>
+#include <sysexits.h>
+#include <sys/types.h>
+#include <machine/cpufunc.h>
+#include <pmc.h>
+
+int
+main(int argc, char **argv)
+{
+ pmc_id_t pmcid;
+ pmc_value_t read_value;
+ pmc_value_t read_clear_value;
+ uint64_t tsc1, write_cyc, start_cyc, read_cyc, stop_cyc;
+ char *counter_name;
+
+ if (argc != 2)
+ err(EX_USAGE, "counter-name required");
+
+ counter_name = argv[1];
+
+ if (pmc_init() != 0)
+ err(EX_OSERR, "hwpmc(4) not loaded, kldload or update your kernel");
+
+ if (pmc_allocate(counter_name, PMC_MODE_SC, 0, 0, &pmcid) < 0)
+ err(EX_OSERR, "failed to allocate %s as a system counter in counting mode",
+ counter_name);
+
+ tsc1 = rdtsc();
+ if (pmc_write(pmcid, 0) < 0)
+ err(EX_OSERR, "failed to zero counter %s", counter_name);
+ write_cyc = rdtsc() - tsc1;
+
+ tsc1 = rdtsc();
+ if (pmc_start(pmcid) < 0)
+ err(EX_OSERR, "failed to start counter %s", counter_name);
+ start_cyc = rdtsc() - tsc1;
+
+ tsc1 = rdtsc();
+ if (pmc_read(pmcid, &read_value) < 0)
+ err(EX_OSERR, "failed to read counter %s", counter_name);
+ read_cyc = rdtsc() - tsc1;
+
+ tsc1 = rdtsc();
+ if (pmc_stop(pmcid) < 0)
+ err(EX_OSERR, "failed to stop counter %s", counter_name);
+ stop_cyc = rdtsc() - tsc1;
+
+ if (pmc_rw(pmcid, 0, &read_clear_value))
+ err(EX_OSERR, "failed to read and zero %s", counter_name);
+
+ if (pmc_release(pmcid) < 0)
+ err(EX_OSERR, "failed to release %s as a system counter in counting mode",
+ counter_name);
+
+ printf("Counter %s, read value %ld, read/clear value %ld\n",
+ counter_name, read_value, read_clear_value);
+ printf("Cycles to start: %ld\tstop: %ld\tread: %ld\twrite: %ld\n",
+ start_cyc, stop_cyc, read_cyc, stop_cyc);
+
+ return(0);
+}
+
diff --git a/share/examples/kld/random_adaptor/random_adaptor_example.c b/share/examples/kld/random_adaptor/random_adaptor_example.c
index da588a8..34993c1 100644
--- a/share/examples/kld/random_adaptor/random_adaptor_example.c
+++ b/share/examples/kld/random_adaptor/random_adaptor_example.c
@@ -35,17 +35,20 @@ __FBSDID("$FreeBSD$");
#include <sys/random.h>
#include <sys/systm.h>
-#include <dev/random/live_entropy_sources.h>
-#include <dev/random/random_adaptors.h>
#include <dev/random/randomdev.h>
+#include <dev/random/randomdev_soft.h>
+#include <dev/random/random_adaptors.h>
+#include <dev/random/live_entropy_sources.h>
-static int random_example_read(void *, int);
+static void live_random_example_init(void);
+static void live_random_example_deinit(void);
+static u_int live_random_example_read(void *, u_int);
-struct random_adaptor random_example = {
- .ident = "Example RNG",
- .source = RANDOM_PURE_BOGUS, /* Make sure this is in
- * sys/random.h and is unique */
- .read = random_example_read,
+struct random_adaptor live_random_example = {
+ .les_ident = "Example RNG",
+ .les_source = RANDOM_PURE_BOGUS, /* Make sure this is in
+ * sys/random.h and is unique */
+ .les_read = live_random_example_read,
};
/*
@@ -58,8 +61,26 @@ getRandomNumber(void)
return 4; /* chosen by fair dice roll, guaranteed to be random */
}
-static int
-random_example_read(void *buf, int c)
+static void
+live_random_example_init(void)
+{
+
+ /* Do initialisation stuff here */
+}
+
+static void
+live_random_example_deinit(void)
+{
+
+ /* Do de-initialisation stuff here */
+}
+
+/* get <c> bytes of random stuff into <buf>. You may presume
+ * that <c> is a multiple of 2^n, with n>=3. A typical value
+ * is c=16.
+ */
+static u_int
+live_random_example_read(void *buf, u_int c)
{
uint8_t *b;
int count;
@@ -69,22 +90,23 @@ random_example_read(void *buf, int c)
for (count = 0; count < c; count++)
b[count] = getRandomNumber();
- printf("returning %d bytes of pure randomness\n", c);
+ /* printf("returning %d bytes of pure randomness\n", c); */
return (c);
}
+/* ARGSUSED */
static int
-random_example_modevent(module_t mod, int type, void *unused)
+live_random_example_modevent(module_t mod __unused, int type, void *unused __unused)
{
int error = 0;
switch (type) {
case MOD_LOAD:
- live_entropy_source_register(&random_example);
+ live_entropy_source_register(&live_random_example);
break;
case MOD_UNLOAD:
- live_entropy_source_deregister(&random_example);
+ live_entropy_source_deregister(&live_random_example);
break;
case MOD_SHUTDOWN:
@@ -98,4 +120,6 @@ random_example_modevent(module_t mod, int type, void *unused)
return (error);
}
-LIVE_ENTROPY_SRC_MODULE(live_entropy_source_example, random_example_modevent, 1);
+DEV_MODULE(live_random_example, live_random_example_modevent, NULL);
+MODULE_VERSION(live_random_example, 1);
+MODULE_DEPEND(live_random_example, randomdev, 1, 1, 1);
OpenPOWER on IntegriCloud