Implement a mechanism for a module to report a small amount of module

specific data back to the user via kldstat(2).  Use that mechanism in
the syscall handler to report the syscall number used.
This commit is contained in:
dfr 1999-01-09 14:59:50 +00:00
parent b43be70fab
commit 3d95b33da8
3 changed files with 45 additions and 4 deletions

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: kern_module.c,v 1.11 1998/10/16 03:55:00 peter Exp $
* $Id: kern_module.c,v 1.12 1998/11/06 02:18:57 peter Exp $
*/
#include <sys/param.h>
@ -48,6 +48,7 @@ struct module {
char *name; /* module name */
modeventhand_t handler; /* event handler */
void *arg; /* argument for handler */
modspecific_t data; /* module specific data */
};
#define MOD_EVENT(mod, type) (mod)->handler((mod), (type), (mod)->arg)
@ -107,6 +108,7 @@ module_register(const char* name, modeventhand_t handler, void* arg, void *file)
strcpy(newmod->name, name);
newmod->handler = handler;
newmod->arg = arg;
bzero(&newmod->data, sizeof(newmod->data));
TAILQ_INSERT_TAIL(&modules, newmod, link);
if (container == NULL)
@ -196,6 +198,12 @@ module_getfnext(module_t mod)
return TAILQ_NEXT(mod, flink);
}
void
module_setspecific(module_t mod, modspecific_t *datap)
{
mod->data = *datap;
}
/*
* Syscalls.
*/
@ -243,6 +251,13 @@ modfnext(struct proc* p, struct modfnext_args* uap)
return 0;
}
struct module_stat_v1 {
int version; /* set to sizeof(struct module_stat) */
char name[MAXMODNAME];
int refs;
int id;
};
int
modstat(struct proc* p, struct modstat_args* uap)
{
@ -263,7 +278,8 @@ modstat(struct proc* p, struct modstat_args* uap)
*/
if (error = copyin(&stat->version, &version, sizeof(version)))
goto out;
if (version != sizeof(struct module_stat)) {
if (version != sizeof(struct module_stat_v1)
&& version != sizeof(struct module_stat)) {
error = EINVAL;
goto out;
}
@ -279,6 +295,15 @@ modstat(struct proc* p, struct modstat_args* uap)
if (error = copyout(&mod->id, &stat->id, sizeof(int)))
goto out;
/*
* >v1 stat includes module data.
*/
if (version == sizeof(struct module_stat)) {
if (error = copyout(&mod->data, &stat->data, sizeof(mod->data)))
goto out;
} else
printf("kldstat: v1 request\n");
p->p_retval[0] = 0;
out:

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: kern_syscalls.c,v 1.1 1999/01/03 06:00:55 root Exp root $
* $Id: kern_syscalls.c,v 1.1 1999/01/09 14:15:41 dfr Exp $
*/
#include <sys/param.h>
@ -72,6 +72,7 @@ int
syscall_module_handler(struct module *mod, int what, void *arg)
{
struct syscall_module_data *data = (struct syscall_module_data*)arg;
modspecific_t ms;
int error;
switch (what) {
@ -80,6 +81,8 @@ syscall_module_handler(struct module *mod, int what, void *arg)
&data->old_sysent);
if (error)
return error;
ms.intval = *data->offset;
module_setspecific(mod, &ms);
break;
case MOD_UNLOAD :
error = syscall_deregister(data->offset, &data->old_sysent);

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: module.h,v 1.4 1998/10/09 23:05:45 peter Exp $
* $Id: module.h,v 1.5 1998/11/14 21:58:41 wollman Exp $
*/
#ifndef _SYS_MODULE_H_
@ -50,6 +50,17 @@ typedef struct moduledata {
void *_file; /* private; used by linker */
} moduledata_t;
/*
* A module can use this to report module specific data to
* the user via kldstat(2).
*/
typedef union modspecific {
int intval;
u_int uintval;
long longval;
u_long ulongval;
} modspecific_t;
#ifdef KERNEL
#define DECLARE_MODULE(name, data, sub, order) \
@ -66,6 +77,7 @@ void module_release(module_t mod);
int module_unload(module_t mod);
int module_getid(module_t mod);
module_t module_getfnext(module_t mod);
void module_setspecific(module_t mod, modspecific_t *datap);
#ifdef MOD_DEBUG
@ -92,6 +104,7 @@ struct module_stat {
char name[MAXMODNAME];
int refs;
int id;
modspecific_t data;
};
#ifndef KERNEL