Skip to content

Instantly share code, notes, and snippets.

@furandon-pig
Created December 12, 2018 18:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save furandon-pig/c35bd3dd418ca0467197d3ca9ed914b8 to your computer and use it in GitHub Desktop.
Save furandon-pig/c35bd3dd418ca0467197d3ca9ed914b8 to your computer and use it in GitHub Desktop.
NetBSDカーネルモジュールでsysctlを実装するサンプルです。
/* $NetBSD: hello.c,v 1.1 2015/05/13 07:07:36 pgoyette Exp $ */
/*-
* Copyright (c) 2015 The NetBSD Foundation, Inc.
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: hello.c,v 1.1 2015/05/13 07:07:36 pgoyette Exp $");
#include <sys/param.h>
#include <sys/fcntl.h>
#include <sys/conf.h>
#include <sys/condvar.h>
#include <sys/device.h>
#include <sys/ioctl.h>
#include <sys/kmem.h>
#include <sys/lock.h>
#include <sys/module.h>
#include <sys/mutex.h>
#include <sys/namei.h>
#include <sys/queue.h>
#include <sys/sysctl.h>
#include <sys/vnode.h>
#include <sys/cpu.h>
struct hello_softc {
device_t sc_dev;
kmutex_t sc_lock;
kcondvar_t sc_inuse_cv;
bool sc_inuse;
/* Locking access to state queues */
kmutex_t sc_state_lock;
kcondvar_t sc_state_cv;
bool sc_state;
struct sysctllog *sc_log;
};
extern struct cfdriver hello_cd;
static device_t sc_self;
static int hello_max_instr;
static int hello_match(device_t, cfdata_t, void *);
static void hello_attach(device_t, device_t, void *);
static int hello_detach(device_t, int);
CFATTACH_DECL_NEW(hello, sizeof(struct hello_softc),
hello_match, hello_attach, hello_detach, NULL);
const struct cdevsw hello_cdevsw = {
.d_open = noopen,
.d_close = noclose,
.d_read = noread,
.d_write = nowrite,
.d_ioctl = noioctl,
.d_stop = nostop,
.d_tty = notty,
.d_poll = nopoll,
.d_mmap = nommap,
.d_kqfilter = nokqfilter,
.d_discard = nodiscard,
.d_flag = D_OTHER | D_MPSAFE
};
MODULE(MODULE_CLASS_MISC, hello, NULL);
#ifdef _MODULE
static const struct cfiattrdata hellobus_iattrdata = {
"hellobus", 0, { { NULL, NULL, 0 },}
};
static const struct cfiattrdata *const hello_attrs[] = {
&hellobus_iattrdata, NULL
};
CFDRIVER_DECL(hello, DV_DULL, hello_attrs);
extern struct cfattach hello_ca;
static int helloloc[] = {
-1,
-1,
-1
};
static struct cfdata hello_cfdata[] = {
{
.cf_name = "hello",
.cf_atname = "hello",
.cf_unit = 0,
.cf_fstate = FSTATE_STAR,
.cf_loc = helloloc,
.cf_flags = 0,
.cf_pspec = NULL,
},
{ NULL, NULL, 0, FSTATE_NOTFOUND, NULL, 0, NULL }
};
#endif
static int
hello_match(device_t parent, cfdata_t match, void *aux)
{
return 1;
}
static void
hello_attach(device_t parent, device_t self, void *aux)
{
struct hello_softc *sc;
const struct sysctlnode *node;
if (sc_self)
return;
sc = device_private(self);
sc->sc_dev = self;
sc_self = self;
/* Sysctl to provide some control over behaviour */
sysctl_createv(&sc->sc_log, 0, NULL, &node,
CTLFLAG_OWNDESC,
CTLTYPE_NODE, "hello",
SYSCTL_DESCR("Hello options"),
NULL, 0, NULL, 0,
CTL_KERN, CTL_CREATE, CTL_EOL);
if (node == NULL) {
printf(": can't create sysctl node\n");
return;
}
sysctl_createv(&sc->sc_log, 0, &node, NULL,
CTLFLAG_READWRITE | CTLFLAG_OWNDESC,
CTLTYPE_INT, "maxcount",
SYSCTL_DESCR("Limit maximum instruction count"),
NULL, 0, &hello_max_instr, 0,
CTL_CREATE, CTL_EOL);
}
static int
hello_detach(device_t self, int flags)
{
struct hello_softc *sc;
sc = device_private(self);
if (sc->sc_log != NULL) {
sysctl_teardown(&sc->sc_log);
sc->sc_log = NULL;
}
return 0;
}
static int
hello_modcmd(modcmd_t cmd, void *arg __unused)
{
#ifdef _MODULE
devmajor_t cmajor, bmajor;
int error = 0;
cmajor = bmajor = NODEVMAJOR;
#endif
switch (cmd) {
case MODULE_CMD_INIT:
printf("Example module loaded.\n");
error = config_cfdriver_attach(&hello_cd);
if (error)
return error;
error = config_cfattach_attach(hello_cd.cd_name, &hello_ca);
if (error) {
config_cfdriver_detach(&hello_cd);
aprint_error("%s: unable to register cfattach\n",
hello_cd.cd_name);
return error;
}
error = config_cfdata_attach(hello_cfdata, 1);
if (error) {
config_cfattach_detach(hello_cd.cd_name, &hello_ca);
config_cfdriver_detach(&hello_cd);
aprint_error("%s: unable to register cfdata\n", hello_cd.cd_name);
return error;
}
error = devsw_attach(hello_cd.cd_name, NULL, &bmajor, &hello_cdevsw, &cmajor);
if (error) {
aprint_error("%s: unable to register devsw\n", hello_cd.cd_name);
config_cfattach_detach(hello_cd.cd_name, &hello_ca);
config_cfdriver_detach(&hello_cd);
return error;
}
config_attach_pseudo(hello_cfdata);
break;
case MODULE_CMD_FINI:
printf("Example module unloaded.\n");
#ifdef _MODULE
error = config_cfdata_detach(hello_cfdata);
if (error)
return error;
config_cfattach_detach(hello_cd.cd_name, &hello_ca);
config_cfdriver_detach(&hello_cd);
devsw_detach(NULL, &hello_cdevsw);
#endif
break;
case MODULE_CMD_STAT:
printf("Example module status queried.\n");
break;
default:
return ENOTTY;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment