Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 03 Aug 2001 13:31:01 -0700
From:      Dima Dorfman <dima@unixfreak.org>
To:        arch@freebsd.org
Subject:   Library routine to load a kld if it already isn't
Message-ID:  <20010803203106.447343E35@bazooka.unixfreak.org>

next in thread | raw e-mail | index | archive | help
Programs that control a certain driver or set of drivers (e.g.,
ifconfig, ccdconfig, mdconfig) attempt to load the module they'll be
working with if it isn't already present.  They do it in different
ways, and the most correct way (i.e., the one that handles the most
cases properly) is liable to change if the kld subsystem ever changes.
I propose to add a library routine, kldmaybeload(3), that will check
if a certain module is present in the kernel, and load it if it isn't.
This will cut down on duplicated code, and may save some headaches
later if the kld interface changes.

Sharball of the implementation and man page is attached (extract into
src/lib/libc/gen).  Comments?  Suggestions?

# This is a shell archive.  Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file".  Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
#	kldmaybeload.c
#	kldmaybeload.3
#
echo x - kldmaybeload.c
sed 's/^X//' >kldmaybeload.c << 'END-of-kldmaybeload.c'
X/*
X * Copyright (c) 2001 Dima Dorfman.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X * 1. Redistributions of source code must retain the above copyright
X *    notice, this list of conditions and the following disclaimer.
X * 2. Redistributions in binary form must reproduce the above copyright
X *    notice, this list of conditions and the following disclaimer in the
X *    documentation and/or other materials provided with the distribution.
X *
X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
X * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
X * SUCH DAMAGE.
X */
X
X#if defined(LIBC_RCS) && !defined(lint)
Xstatic const char rcsid[] =
X  "$FreeBSD$";
X#endif /* LIBC_RCS and not lint */
X
X#include <sys/param.h>
X#include <sys/linker.h>
X#include <sys/module.h>
X
X#include <errno.h>
X#include <string.h>
X#include <unistd.h>
X
Xint
Xkldmaybeload(const char *modname)
X{
X	struct module_stat ms;
X	int fid, mid;
X	char *cp;
X
X	ms.version = sizeof(ms);
X	/*
X	 * Walk the list of loaded modules.  We have to do this by
X	 * walking the list of loaded files, then walking the modules
X	 * in them using modfnext().  The latter will return 0 when
X	 * we've reached the last module in the file.  This is
X	 * contrary to the documentation, which says it will return
X	 * the ID of "the next kernel module", and says nothing about
X	 * files. XXX
X	 */
X	for (fid = kldnext(0); fid != 0; fid = kldnext(fid)) {
X		for (mid = kldfirstmod(fid); mid != 0; mid = modfnext(mid)) {
X			if (modstat(mid, &ms) == -1)
X				/*
X				 * This really shouldn't happen,
X				 * because modstat() can't fail for
X				 * any reason that wouldn't indicate a
X				 * bug either in the kernel, or in
X				 * this function.
X				 */
X				return (-1);
X			/*
X			 * Some modules have a bus name in their name,
X			 * e.g. "pci/if_fxp".  We were given a name
X			 * without the bus name, so we have to strip
X			 * it off it it's there before we do the
X			 * comparison.
X			 */
X			cp = strchr(ms.name, '/');
X			if (cp != NULL)
X				cp++;
X			else
X				cp = ms.name;
X			if (strcmp(modname, cp) == 0)
X				/* Already loaded. */
X				return (0);
X		}
X	}
X	/* We didn't find it, so it must not be present.  Load it. */
X	return (kldload(modname));
X}
END-of-kldmaybeload.c
echo x - kldmaybeload.3
sed 's/^X//' >kldmaybeload.3 << 'END-of-kldmaybeload.3'
X.\"
X.\" Copyright (c) 2001 Dima Dorfman.
X.\" All rights reserved.
X.\"
X.\" Redistribution and use in source and binary forms, with or without
X.\" modification, are permitted provided that the following conditions
X.\" are met:
X.\" 1. Redistributions of source code must retain the above copyright
X.\"    notice, this list of conditions and the following disclaimer.
X.\" 2. Redistributions in binary form must reproduce the above copyright
X.\"    notice, this list of conditions and the following disclaimer in the
X.\"    documentation and/or other materials provided with the distribution.
X.\"
X.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
X.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
X.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
X.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
X.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
X.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
X.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
X.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
X.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
X.\" SUCH DAMAGE.
X.\"
X.\" $FreeBSD$
X.\"
X.Dd July 31, 2001
X.Dt KLDMAYBELOAD 3
X.Os
X.Sh NAME
X.Nm kldmaybeload
X.Nd load a kernel module if it isn't already present
X.Sh LIBRARY
X.Lb libc
X.Sh SYNOPSIS
X.In unistd.h
X.Ft int
X.Fn kldmaybeload "const char *modname"
X.Sh DESCRIPTION
XThe
X.Fn kldmaybeload
Xfunction checks if the module referenced by
X.Fa modname
Xis already present in the kernel (either by being already loaded, or
Xstatically compiled in), and loads it if it isn't.
X.Sh RETURN VALUES
XIf the module is already present or has been successfully loaded,
X0 is returned; otherwise, if the module is not present and could not
Xbe loaded, \-1 is returned and
X.Va errno
Xis set to indicate the error.
X.Sh ERRORS
XAn attempt to load the module may fail for the following reasons:
X.Bl -tag -width Er
X.It Bq Er EPERM
XPermission is denied to read the module file or link it with the kernel.
X.It Bq Er EFAULT
X.Fa modname
Xpoints outside the process's allocated address space, or
Xa bad address was encountered when trying to link the module.
X.It Bq Er ENOMEM
XThere was insufficient memory to service the request.
X.It Bq Er ENOENT
XThe module file could not be found.
X.It Bq Er ENOEXEC
XThe format of the module file was unrecognized.
X.El
X.Sh SEE ALSO
X.Xr modfind 2 ,
X.Xr kldload 2 ,
X.Xr kld 4 ,
X.Xr kldconfig ,
X.Xr kldload 8
X.Sh HISTORY
XThe
X.Fn kldmaybeload
Xfunction appeared in
X.Fx 5.0 .
END-of-kldmaybeload.3
exit



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-arch" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010803203106.447343E35>