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@xxxxxxxxxx> > --- > 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
Attachment:
signature.asc
Description: OpenPGP digital signature
-- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list