Add -A, -a, and -e options to modstat(8) along with kernel

changes required to support these options.  The -e option was
requested by martin@ in private chat in order to make writing tests
easier (i.e. don't bother testing MODULAR functionaility if it
doesn't exist).  While there, I added -A and -a since those were
quite similar.

     -A      Tells you whether or not modules can be autoloaded at the moment.
             This option does take into consideration the sysctl
             kern.module.autoload.

     -a      Tells you whether or not modules can be autoloaded at the moment.
             This option does not take into consideration the sysctl
             kern.module.autoload.

     -e      Tells you whether or not you may load a module at the moment.
This commit is contained in:
jnemeth 2012-08-07 01:19:05 +00:00
parent a4ae934e29
commit 942121f54c
6 changed files with 145 additions and 21 deletions

View File

@ -1,4 +1,4 @@
# LIST OF CHANGES FROM LAST RELEASE: <$Revision: 1.1729 $>
# LIST OF CHANGES FROM LAST RELEASE: <$Revision: 1.1730 $>
#
#
# [Note: This file does not mention every change made to the NetBSD source tree.
@ -86,7 +86,7 @@ Changes from NetBSD 6.0 to NetBSD 7.0:
tdvfb(4): Add 3Dfx Voodoo Graphics (aka Voodoo1) support.
[rkujawa 20120720]
kernel: Change mii_statchg to take "struct ifnet *" instead of
"device_t". [matt 20120722]
"device_t". [matt 20120722]
pr(1): Add support for POSIX -f and -p options. [ginsbach 20120724]
powerpc: Add support for FPU emulation on BookE. [matt 20120722]
zoneinfo: Import tzdata2012d. [apb 20120722]
@ -94,6 +94,11 @@ Changes from NetBSD 6.0 to NetBSD 7.0:
OpenSSL: Imported 1.0.1c [christos 20120726]
kernel: safepri is dead; replaced by macro IPL_SAFEPRI. [matt 20120727]
kernel: Add malo(4), a driver for Marvell Libertas IEEE 802.11b/g
wireless network devices, ported from OpenBSD. [degroote 20120730]
wireless network devices, ported from OpenBSD.
[degroote 20120730]
kernel: Add BPF JIT compiler, currently supporting amd64 and i386.
[rmind 20120802]
kernel, libc: Add modctl(MODCTL_EXISTS, ...) to determine if modules
can be loaded. [jnemeth 20120803]
modstat(8): Add -A, -a, and -e options for testing module loadability.
[jnemeth 20120803]

View File

@ -1,4 +1,4 @@
.\" $NetBSD: modctl.2,v 1.8 2010/12/14 16:23:59 jruoho Exp $
.\" $NetBSD: modctl.2,v 1.9 2012/08/07 01:19:05 jnemeth Exp $
.\"
.\" Copyright (c) 2009 The NetBSD Foundation, Inc.
.\" All rights reserved.
@ -24,7 +24,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd December 14, 2010
.Dd August 3, 2012
.Dt MODCTL 2
.Os
.Sh NAME
@ -44,8 +44,9 @@ The argument
is one of
.Dv MODCTL_LOAD ,
.Dv MODCTL_UNLOAD ,
.Dv MODCTL_STAT ,
or
.Dv MODCTL_STAT .
.Dv MODCTL_EXISTS .
The argument
.Fa argp
depends on the
@ -84,6 +85,24 @@ member of the
.Em iovec
to reflect the size of the complete report, regardless of whether this
is larger or smaller than the size passed in.
.It Dv MODCTL_EXISTS
Test to see if the kernel was compiled with
.Dq options MODULAR
and whether or
not modules may be loaded at the moment.
In this case,
.Fa argp
should be an integer.
It should be
.Dq 0
to test if a user can load a module via
.Dv MODCTL_LOAD ,
or it should be
.Dq 1
to test if the system can autoload modules.
Note that this
test does not consider the sysctl
.Li kern.module.autoload .
.El
.Ss Data Types
The
@ -98,7 +117,8 @@ The name/path of the module to load.
Zero or more of the following flag values:
.Bl -tag -compact -width "MODCTL_LOAD_FORCE"
.It Dv MODCTL_NO_PROP
Don't load \*[Lt]module\*[Gt].plist.
Don't load
.Ao module Ac Ns Pa .plist .
.It Dv MODCTL_LOAD_FORCE
Ignore kernel version mismatch.
.El
@ -271,6 +291,7 @@ information.
.El
.Sh SEE ALSO
.Xr module 7 ,
.Xr sysctl 7 ,
.Xr module 9
.Sh HISTORY
The

View File

@ -1,4 +1,4 @@
/* $NetBSD: main.c,v 1.14 2011/08/02 16:46:45 mbalmer Exp $ */
/* $NetBSD: main.c,v 1.15 2012/08/07 01:19:05 jnemeth Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@ -28,16 +28,19 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: main.c,v 1.14 2011/08/02 16:46:45 mbalmer Exp $");
__RCSID("$NetBSD: main.c,v 1.15 2012/08/07 01:19:05 jnemeth Exp $");
#endif /* !lint */
#include <sys/module.h>
#include <sys/param.h>
#include <sys/sysctl.h>
#include <err.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <err.h>
#include "prog_ops.h"
@ -70,13 +73,19 @@ main(int argc, char **argv)
size_t len;
const char *name;
char sbuf[32];
int ch;
size_t maxnamelen = 16, i;
int ch, rc, modauto = 1;
size_t maxnamelen = 16, i, modautolen;
char loadable = '\0';
name = NULL;
while ((ch = getopt(argc, argv, "n:")) != -1) {
while ((ch = getopt(argc, argv, "Aaen:")) != -1) {
switch (ch) {
case 'A': /* FALLTHROUGH */
case 'a': /* FALLTHROUGH */
case 'e':
loadable = (char)ch;
break;
case 'n':
name = optarg;
break;
@ -96,6 +105,56 @@ main(int argc, char **argv)
if (prog_init && prog_init() == -1)
err(1, "prog init failed");
if (loadable == 'A' || loadable == 'a') {
if (prog_modctl(MODCTL_EXISTS, (void *)(uintptr_t)1)) {
switch (errno) {
case ENOSYS:
errx(EXIT_FAILURE, "The kernel was compiled "
"without options MODULAR.");
break;
case EPERM:
errx(EXIT_FAILURE, "Modules can not be "
"autoloaded right now.");
break;
default:
err(EXIT_FAILURE, "modctl_exists for autoload");
break;
}
} else {
if (loadable == 'A') {
modautolen = sizeof(modauto);
rc = sysctlbyname("kern.module.autoload",
&modauto, &modautolen, NULL, 0);
if (rc != 0) {
err(EXIT_FAILURE, "sysctl "
"kern.module.autoload failed.");
}
}
errx(EXIT_SUCCESS, "Modules can be autoloaded%s.",
modauto ? "" : ", but kern.module.autoload = 0");
}
}
if (loadable == 'e') {
if (prog_modctl(MODCTL_EXISTS, (void *)(uintptr_t)0)) {
switch (errno) {
case ENOSYS:
errx(EXIT_FAILURE, "The kernel was compiled "
"without options MODULAR.");
break;
case EPERM:
errx(EXIT_FAILURE, "You are not allowed to "
"load modules right now.");
break;
default:
err(EXIT_FAILURE, "modctl_exists for autoload");
break;
}
} else {
errx(EXIT_SUCCESS, "You can load modules.");
}
}
for (len = 8192;;) {
iov.iov_base = malloc(len);
iov.iov_len = len;
@ -157,7 +216,7 @@ static void
usage(void)
{
(void)fprintf(stderr, "Usage: %s [-n] [name]\n", getprogname());
(void)fprintf(stderr, "Usage: %s [-Aaen] [name]\n", getprogname());
exit(EXIT_FAILURE);
}

View File

@ -1,4 +1,4 @@
.\" $NetBSD: modstat.8,v 1.9 2011/08/02 16:46:45 mbalmer Exp $
.\" $NetBSD: modstat.8,v 1.10 2012/08/07 01:19:05 jnemeth Exp $
.\"
.\" Copyright (c) 1993 Christopher G. Demetriou
.\" All rights reserved.
@ -32,7 +32,7 @@
.\"
.\" <<Id: LICENSE,v 1.2 2000/06/14 15:57:33 cgd Exp>>
.\"
.Dd August 2, 2011
.Dd August 6, 2012
.Dt MODSTAT 8
.Os
.Sh NAME
@ -40,7 +40,7 @@
.Nd display status of loaded kernel modules
.Sh SYNOPSIS
.Nm
.Op Fl n
.Op Fl Aaen
.Op Ar name
.Sh DESCRIPTION
The
@ -49,6 +49,16 @@ utility displays the status of any kernel modules present in the kernel.
.Pp
The options are as follows:
.Bl -tag -width indent
.It Fl A
Tells you whether or not modules can be autoloaded at the moment.
This option does take into consideration the sysctl
.Li kern.module.autoload .
.It Fl a
Tells you whether or not modules can be autoloaded at the moment.
This option does not take into consideration the sysctl
.Li kern.module.autoload .
.It Fl e
Tells you whether or not you may load a module at the moment.
.It Fl n Ar name
Display the status of only the module with this name.
Please note that
@ -88,6 +98,7 @@ utility exits with a status of 0 on success
and with a nonzero status if an error occurs.
.Sh SEE ALSO
.Xr module 7 ,
.Xr sysctl 7 ,
.Xr modload 8 ,
.Xr modunload 8
.Sh HISTORY

View File

@ -1,4 +1,4 @@
/* $NetBSD: sys_module.c,v 1.13 2011/07/08 09:32:45 mrg Exp $ */
/* $NetBSD: sys_module.c,v 1.14 2012/08/07 01:19:05 jnemeth Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@ -31,18 +31,21 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sys_module.c,v 1.13 2011/07/08 09:32:45 mrg Exp $");
__KERNEL_RCSID(0, "$NetBSD: sys_module.c,v 1.14 2012/08/07 01:19:05 jnemeth Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/namei.h>
#include <sys/kauth.h>
#include <sys/kmem.h>
#include <sys/kobj.h>
#include <sys/module.h>
#include <sys/syscall.h>
#include <sys/syscallargs.h>
#include <opt_modular.h>
static int
handle_modctl_load(modctl_load_t *ml)
{
@ -121,6 +124,9 @@ sys_modctl(struct lwp *l, const struct sys_modctl_args *uap,
modctl_load_t ml;
int error;
void *arg;
#ifdef MODULAR
uintptr_t loadtype;
#endif
arg = SCARG(uap, arg);
@ -197,6 +203,27 @@ sys_modctl(struct lwp *l, const struct sys_modctl_args *uap,
}
break;
case MODCTL_EXISTS:
#ifndef MODULAR
error = ENOSYS;
#else
loadtype = (uintptr_t)arg;
switch (loadtype) { /* 0 = modload, 1 = autoload */
case 0: /* FALLTHROUGH */
case 1:
error = kauth_authorize_system(kauth_cred_get(),
KAUTH_SYSTEM_MODULE, 0,
(void *)(uintptr_t)MODCTL_LOAD,
(void *)loadtype, NULL);
break;
default:
error = EINVAL;
break;
}
#endif
break;
default:
error = EINVAL;
break;

View File

@ -1,4 +1,4 @@
/* $NetBSD: module.h,v 1.30 2011/11/21 04:36:05 christos Exp $ */
/* $NetBSD: module.h,v 1.31 2012/08/07 01:19:06 jnemeth Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@ -179,7 +179,8 @@ typedef struct modctl_load {
typedef enum modctl {
MODCTL_LOAD, /* modctl_load_t *ml */
MODCTL_UNLOAD, /* char *name */
MODCTL_STAT /* struct iovec *buffer */
MODCTL_STAT, /* struct iovec *buffer */
MODCTL_EXISTS /* enum: 0: load, 1: autoload */
} modctl_t;
/*