[libvirt] [PATCH v3 1/3] utils: Introduce functions for modprobe

Ján Tomko jtomko at redhat.com
Tue Feb 4 11:06:03 UTC 2014


On 01/30/2014 06:50 PM, John Ferlan wrote:
> This patch adds functions for various usages of modprobe
> 
> Signed-off-by: John Ferlan <jferlan at redhat.com>
> ---
>  configure.ac             |   6 ++
>  src/Makefile.am          |   1 +
>  src/libvirt_private.syms |   7 ++
>  src/util/virkmod.c       | 182 +++++++++++++++++++++++++++++++++++++++++++++++
>  src/util/virkmod.h       |  34 +++++++++
>  5 files changed, 230 insertions(+)
>  create mode 100644 src/util/virkmod.c
>  create mode 100644 src/util/virkmod.h
> 
> diff --git a/configure.ac b/configure.ac
> index 1670a41..eb11e3b 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -405,6 +405,8 @@ AC_PATH_PROG([UDEVSETTLE], [udevsettle], [],
>  	[/sbin:/usr/sbin:/usr/local/sbin:$PATH])
>  AC_PATH_PROG([MODPROBE], [modprobe], [modprobe],
>  	[/sbin:/usr/sbin:/usr/local/sbin:$PATH])
> +AC_PATH_PROG([RMMOD], [rmmod], [rmmod],
> +	[/sbin:/usr/sbin:/usr/local/sbin:$PATH])
>  AC_PATH_PROG([OVSVSCTL], [ovs-vsctl], [ovs-vsctl],
>  	[/sbin:/usr/sbin:/usr/local/sbin:$PATH])
>  AC_PATH_PROG([SCRUB], [scrub], [scrub],
> @@ -433,6 +435,10 @@ if test -n "$MODPROBE"; then
>    AC_DEFINE_UNQUOTED([MODPROBE],["$MODPROBE"],
>          [Location or name of the modprobe program])
>  fi
> +if test -n "$RMMOD"; then
> +  AC_DEFINE_UNQUOTED([RMMOD],["$RMMOD"],
> +        [Location or name of the rmmod program])
> +fi
>  AC_DEFINE_UNQUOTED([SCRUB],["$SCRUB"],
>          [Location or name of the scrub program (for wiping algorithms)])
>  
> diff --git a/src/Makefile.am b/src/Makefile.am
> index abe0a51..b704045 100644
> --- a/src/Makefile.am
> +++ b/src/Makefile.am
> @@ -125,6 +125,7 @@ UTIL_SOURCES =							\
>  		util/virnetdevvportprofile.h util/virnetdevvportprofile.c \
>  		util/virnetlink.c util/virnetlink.h		\
>  		util/virnodesuspend.c util/virnodesuspend.h	\
> +		util/virkmod.c util/virkmod.h                   \
>  		util/virnuma.c util/virnuma.h			\
>  		util/virobject.c util/virobject.h		\
>  		util/virpci.c util/virpci.h			\
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index 45f3117..372231c 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -1382,6 +1382,13 @@ virKeyFileLoadFile;
>  virKeyFileNew;
>  
>  
> +# util/virkmod.h
> +virKModConfig;

Do we need to export KModConfig as well?

> +virKModIsBlacklisted;
> +virKModLoad;
> +virKModUnload;
> +
> +
>  # util/virlockspace.h
>  virLockSpaceAcquireResource;
>  virLockSpaceCreateResource;
> diff --git a/src/util/virkmod.c b/src/util/virkmod.c
> new file mode 100644
> index 0000000..d39a2e3
> --- /dev/null
> +++ b/src/util/virkmod.c
> @@ -0,0 +1,182 @@
> +/*
> + * virkmod.c: helper APIs for managing kernel modules
> + *
> + * Copyright (C) 2014 Red Hat, Inc.
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library.  If not, see
> + * <http://www.gnu.org/licenses/>.
> + *
> + */
> +
> +#include <config.h>
> +#include "viralloc.h"
> +#include "virkmod.h"
> +#include "vircommand.h"
> +#include "virstring.h"
> +
> +static int
> +doModprobe(const char *opts, const char *module, char **outbuf, char **errbuf)
> +{
> +    int ret = -1;
> +    virCommandPtr cmd = NULL;
> +
> +    cmd = virCommandNew(MODPROBE);
> +    if (opts)
> +        virCommandAddArg(cmd, opts);
> +    if (module)
> +        virCommandAddArg(cmd, module);
> +    if (outbuf)
> +        virCommandSetOutputBuffer(cmd, outbuf);
> +    if (errbuf)
> +        virCommandSetErrorBuffer(cmd, errbuf);
> +
> +    if (virCommandRun(cmd, NULL) < 0)
> +        goto cleanup;
> +
> +    ret = 0;
> +
> +cleanup:
> +    virCommandFree(cmd);
> +    return ret;
> +}
> +
> +static int
> +doRmmod(const char *module, char **errbuf)
> +{
> +    int ret = -1;
> +    virCommandPtr cmd = NULL;
> +
> +    cmd = virCommandNewArgList(RMMOD, module, NULL);
> +    virCommandSetErrorBuffer(cmd, errbuf);
> +
> +    if (virCommandRun(cmd, NULL) < 0)
> +        goto cleanup;
> +
> +    ret = 0;
> +
> +cleanup:
> +    virCommandFree(cmd);
> +    return ret;
> +}
> +
> +/**
> + * virKModConfig:
> + *
> + * Get the current kernel module configuration
> + *
> + * Returns NULL on failure or a pointer to the output which
> + * must be VIR_FREE()'d by the caller
> + */
> +char *
> +virKModConfig(void)
> +{
> +    char *outbuf = NULL;
> +
> +    if (doModprobe("-c", NULL, &outbuf, NULL) < 0)
> +        return NULL;
> +
> +    return outbuf;
> +}
> +
> +
> +/**
> + * virKModLoad:
> + * @module: Name of the module to load
> + * @useBlacklist: True if honoring blacklist
> + *
> + * Attempts to load a kernel module
> + *
> + * returns NULL in case of success and the error buffer output from the
> + * virCommandRun() on failure.  The returned buffer must be VIR_FREE()
> + * by the caller
> + */

It would be nicer if these functions could detect if the module was loaded and
report an error.

> +char *
> +virKModLoad(const char *module, bool useBlacklist)
> +{
> +    char *errbuf = NULL;
> +
> +    if (doModprobe(useBlacklist ? "-b" : NULL, module, NULL, &errbuf) < 0)
> +        return errbuf;
> +
> +    VIR_FREE(errbuf);
> +    return NULL;
> +}
> +
> +
> +/**
> + * virKModUnload:
> + * @module: Name of the module to unload
> + *
> + * Remove or unload a module.
> + *
> + * NB: Do not use 'modprobe -r' here as that code will recursively
> + * unload any modules that were dependancies of the one being removed
> + * even if things still require them. e.g. it'll see the 'bridge'
> + * module has refcount of 0 and remove it, even if there are bridges
> + * created on the host
> + *
> + * returns NULL in case of success and the error buffer output from the
> + * virCommandRun() on failure.  The returned buffer must be VIR_FREE()
> + * by the caller
> + */
> +char *
> +virKModUnload(const char *module)
> +{
> +    char *errbuf = NULL;
> +
> +    if (doRmmod(module, &errbuf) < 0)
> +        return errbuf;
> +
> +    VIR_FREE(errbuf);
> +    return NULL;
> +}
> +
> +
> +/**
> + * virKModIsBlacklisted:
> + * @module: Name of the module to check for on the blacklist
> + *
> + * Search the output of the configuration data for the module being
> + * blacklisted.
> + *
> + * returns true when found blacklisted, false otherwise.
> + */
> +bool
> +virKModIsBlacklisted(const char *module)
> +{
> +    bool retval = false;
> +    size_t i;
> +    char *drvblklst = NULL;
> +    char *outbuf = NULL;
> +
> +    if (virAsprintfQuiet(&drvblklst, "blacklist %s", module) < 0)

I would add a trailing '\n' here.

> +        goto cleanup;
> +
> +    /* modprobe will convert all '-' into '_', so we need to as well */
> +    for (i = 0; i < drvblklst[i]; i++)
> +        if (drvblklst[i] == '-')
> +            drvblklst[i] = '_';
> +
> +    if (doModprobe("-c", NULL, &outbuf, NULL) < 0)
> +        goto cleanup;
> +
> +    /* Find module on blacklist? */

s/Find/Found/

> +    if (strstr(outbuf, drvblklst))
> +        retval = true;
> +
> +cleanup:
> +    VIR_FREE(drvblklst);
> +    VIR_FREE(outbuf);
> +    return retval;
> +}

ACK

Jan


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: OpenPGP digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20140204/a1fd0a76/attachment-0001.sig>


More information about the libvir-list mailing list