diff options
author | sjg <sjg@FreeBSD.org> | 2014-11-19 01:07:58 +0000 |
---|---|---|
committer | sjg <sjg@FreeBSD.org> | 2014-11-19 01:07:58 +0000 |
commit | b137080f19736ee33fede2e88bb54438604cf86b (patch) | |
tree | 377ac0ac449528621eb192cd245adadb5fd53668 /share/examples | |
parent | ab21a29eb607d4dfe389b965fbdee27558e791aa (diff) | |
parent | 4a8d07956d121238d006d34ffe7d6269744e8b1a (diff) | |
download | FreeBSD-src-b137080f19736ee33fede2e88bb54438604cf86b.zip FreeBSD-src-b137080f19736ee33fede2e88bb54438604cf86b.tar.gz |
Merge from head@274682
Diffstat (limited to 'share/examples')
-rw-r--r-- | share/examples/autofs/driver/Makefile | 18 | ||||
-rw-r--r-- | share/examples/autofs/driver/autodriver.c | 538 | ||||
-rw-r--r-- | share/examples/autofs/driver/autotab | 7 | ||||
-rwxr-xr-x | share/examples/bhyve/vmrun.sh | 36 | ||||
-rw-r--r-- | share/examples/hwpmc/Makefile | 9 | ||||
-rw-r--r-- | share/examples/hwpmc/README | 2 | ||||
-rw-r--r-- | share/examples/hwpmc/overhead.c | 106 | ||||
-rw-r--r-- | share/examples/kld/random_adaptor/random_adaptor_example.c | 54 |
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); |