utils: Introduce functions for kernel module manipulation

virKModConfig()        - Return a buffer containing kernel module configuration
virKModLoad()          - Load a specific module into the kernel configuration
virKModUnload()        - Unload a specific module from the kernel configuration
virKModIsBlacklisted() - Determine whether a module is blacklisted within
                         the kernel configuration
This commit is contained in:
John Ferlan 2014-01-29 09:36:26 -05:00
parent 0d0a7bf45a
commit 4a2179ea92
5 changed files with 229 additions and 0 deletions

View File

@ -416,6 +416,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],
@ -444,6 +446,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)])

View File

@ -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 \

View File

@ -1383,6 +1383,13 @@ virKeyFileLoadFile;
virKeyFileNew;
# util/virkmod.h
virKModConfig;
virKModIsBlacklisted;
virKModLoad;
virKModUnload;
# util/virlockspace.h
virLockSpaceAcquireResource;
virLockSpaceCreateResource;

181
src/util/virkmod.c Normal file
View File

@ -0,0 +1,181 @@
/*
* 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
*/
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\n", module) < 0)
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;
if (strstr(outbuf, drvblklst))
retval = true;
cleanup:
VIR_FREE(drvblklst);
VIR_FREE(outbuf);
return retval;
}

34
src/util/virkmod.h Normal file
View File

@ -0,0 +1,34 @@
/*
* virkmod.h: helper APIs for managing kernel modprobe
*
* 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/>.
*
*/
#ifndef __VIR_KMOD_H__
# define __VIR_KMOD_H__
# include "internal.h"
char *virKModConfig(void);
char *virKModLoad(const char *, bool)
ATTRIBUTE_NONNULL(1);
char *virKModUnload(const char *)
ATTRIBUTE_NONNULL(1);
bool virKModIsBlacklisted(const char *)
ATTRIBUTE_NONNULL(1);
#endif /* __VIR_KMOD_H__ */