bumblebee: Add patch to recursively unload nvidia* modules
This commit is contained in:
parent
df9807f638
commit
96fedc124d
|
@ -0,0 +1,18 @@
|
||||||
|
Source: https://github.com/Bumblebee-Project/Bumblebee/commit/1ada79fe5916961fc4e4917f8c63bb184908d986
|
||||||
|
Upstream: From devel branch
|
||||||
|
Reason: Required for "20-better-module-load-unload.patch" to be successfully applied.
|
||||||
|
|
||||||
|
diff --git src/module.c src/module.c
|
||||||
|
index f7b99fa..f6d7144 100644
|
||||||
|
--- src/module.c
|
||||||
|
+++ src/module.c
|
||||||
|
@@ -96,7 +96,8 @@ int module_unload(char *driver) {
|
||||||
|
int retries = 30;
|
||||||
|
bb_log(LOG_INFO, "Unloading %s driver\n", driver);
|
||||||
|
char *mod_argv[] = {
|
||||||
|
- "rmmod",
|
||||||
|
+ "modprobe",
|
||||||
|
+ "-r",
|
||||||
|
driver,
|
||||||
|
NULL
|
||||||
|
};
|
|
@ -0,0 +1,641 @@
|
||||||
|
Source: https://github.com/Bumblebee-Project/Bumblebee/pull/762
|
||||||
|
Upstream: PR merged into into devel branch
|
||||||
|
Reason: Replaces modprobe with libkmod2, and adds recursive module unloading for modern nvidia driver support.
|
||||||
|
|
||||||
|
diff --git Makefile.am Makefile.am
|
||||||
|
index e690362..732e303 100644
|
||||||
|
--- Makefile.am
|
||||||
|
+++ Makefile.am
|
||||||
|
@@ -10,7 +10,7 @@ AM_CPPFLAGS = ${regular_CPPFLAGS} \
|
||||||
|
-DCONF_XORG='"$(bumblebeedconfdir)/xorg.conf.DRIVER"' \
|
||||||
|
-DCONF_XORG_DIR='"$(bumblebeedconfdir)/xorg.conf.d"'
|
||||||
|
AM_CFLAGS = ${regular_CFLAGS} \
|
||||||
|
- ${x11_CFLAGS} ${libbsd_CFLAGS} ${glib_CFLAGS} \
|
||||||
|
+ ${x11_CFLAGS} ${libbsd_CFLAGS} ${glib_CFLAGS} ${kmod_CFLAGS} \
|
||||||
|
-Wextra -funsigned-char -DGITVERSION='"${GITVERSION}"'
|
||||||
|
|
||||||
|
noinst_SCRIPTS = scripts/systemd/bumblebeed.service \
|
||||||
|
@@ -50,12 +50,12 @@ bin_PROGRAMS = bin/optirun
|
||||||
|
|
||||||
|
bin_optirun_SOURCES = src/module.c src/bbconfig.c src/bblogger.c src/bbrun.c \
|
||||||
|
src/bbsocket.c src/driver.c src/optirun.c src/bbsocketclient.c
|
||||||
|
-bin_optirun_LDADD = ${glib_LIBS} -lrt
|
||||||
|
+bin_optirun_LDADD = ${glib_LIBS} ${kmod_LIBS} -lrt
|
||||||
|
bin_bumblebeed_SOURCES = src/pci.c src/bbconfig.c src/bblogger.c src/bbrun.c \
|
||||||
|
src/bbsocket.c src/module.c src/bbsecondary.c src/switch/switching.c \
|
||||||
|
src/switch/sw_bbswitch.c src/switch/sw_switcheroo.c \
|
||||||
|
src/driver.c src/bumblebeed.c
|
||||||
|
-bin_bumblebeed_LDADD = ${x11_LIBS} ${libbsd_LIBS} ${glib_LIBS} -lrt
|
||||||
|
+bin_bumblebeed_LDADD = ${x11_LIBS} ${libbsd_LIBS} ${glib_LIBS} ${kmod_LIBS} -lrt
|
||||||
|
|
||||||
|
dist_doc_DATA = $(relnotes) README.markdown
|
||||||
|
bumblebeedconf_DATA = conf/bumblebee.conf conf/xorg.conf.nouveau conf/xorg.conf.nvidia
|
||||||
|
diff --git README.markdown README.markdown
|
||||||
|
index b534a6c..5c2baa5 100644
|
||||||
|
--- README.markdown
|
||||||
|
+++ README.markdown
|
||||||
|
@@ -19,6 +19,7 @@ The following packages are dependencies for the build process:
|
||||||
|
- pkg-config
|
||||||
|
- glib-2.0 and development headers
|
||||||
|
- libx11 and development headers
|
||||||
|
+- libkmod2 and development headers
|
||||||
|
- libbsd and development headers (if pidfile support is enabled, default yes)
|
||||||
|
- help2man (optional, it is needed for building manual pages)
|
||||||
|
|
||||||
|
diff --git configure.ac configure.ac
|
||||||
|
index 8dd831a..067c1f8 100644
|
||||||
|
--- configure.ac
|
||||||
|
+++ configure.ac
|
||||||
|
@@ -122,6 +122,7 @@ AC_SUBST([regular_CFLAGS])
|
||||||
|
# Checks for header files.
|
||||||
|
PKG_CHECK_MODULES([x11], [x11])
|
||||||
|
PKG_CHECK_MODULES([glib], [glib-2.0])
|
||||||
|
+PKG_CHECK_MODULES([kmod], [libkmod])
|
||||||
|
AS_IF([test "x$with_pidfile" != xno], [
|
||||||
|
PKG_CHECK_MODULES([libbsd], [libbsd >= 0.2.0])
|
||||||
|
PKG_CHECK_EXISTS([libbsd = 0.2.0], [AC_DEFINE(HAVE_LIBBSD_020)])
|
||||||
|
diff --git src/bbconfig.h src/bbconfig.h
|
||||||
|
index 5596b64..c6ebb28 100644
|
||||||
|
--- src/bbconfig.h
|
||||||
|
+++ src/bbconfig.h
|
||||||
|
@@ -26,6 +26,7 @@
|
||||||
|
#include <unistd.h> //for pid_t
|
||||||
|
#include <limits.h> //for CHAR_MAX
|
||||||
|
#include <glib.h>
|
||||||
|
+#include <libkmod.h>
|
||||||
|
|
||||||
|
/* Daemon states */
|
||||||
|
#define BB_DAEMON 1
|
||||||
|
@@ -118,6 +119,7 @@ struct bb_status_struct {
|
||||||
|
int x_pipe[2];//pipes for reading/writing output from X's stdout/stderr
|
||||||
|
gboolean use_syslog;
|
||||||
|
char *program_name;
|
||||||
|
+ struct kmod_ctx *kmod_ctx;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Structure containing the configuration. */
|
||||||
|
diff --git src/bumblebeed.c src/bumblebeed.c
|
||||||
|
index a911da9..ef4a568 100644
|
||||||
|
--- src/bumblebeed.c
|
||||||
|
+++ src/bumblebeed.c
|
||||||
|
@@ -34,6 +34,7 @@
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
+#include <libkmod.h>
|
||||||
|
#ifdef WITH_PIDFILE
|
||||||
|
#ifdef HAVE_LIBBSD_020
|
||||||
|
#include <libutil.h>
|
||||||
|
@@ -500,6 +501,16 @@ int main(int argc, char* argv[]) {
|
||||||
|
|
||||||
|
/* dump the config after detecting the driver */
|
||||||
|
config_dump();
|
||||||
|
+
|
||||||
|
+ // kmod context have to be available for config validation
|
||||||
|
+ const char *null_cfg = NULL;
|
||||||
|
+ bb_status.kmod_ctx = kmod_new(NULL, &null_cfg);
|
||||||
|
+ if (bb_status.kmod_ctx == NULL) {
|
||||||
|
+ bb_log(LOG_ERR, "kmod_new() failed!\n");
|
||||||
|
+ bb_closelog();
|
||||||
|
+ exit(EXIT_FAILURE);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (config_validate() != 0) {
|
||||||
|
return (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
@@ -572,5 +583,7 @@ int main(int argc, char* argv[]) {
|
||||||
|
//close X pipe, if any parts of it are open still
|
||||||
|
if (bb_status.x_pipe[0] != -1){close(bb_status.x_pipe[0]); bb_status.x_pipe[0] = -1;}
|
||||||
|
if (bb_status.x_pipe[1] != -1){close(bb_status.x_pipe[1]); bb_status.x_pipe[1] = -1;}
|
||||||
|
+ //cleanup kmod context
|
||||||
|
+ kmod_unref(bb_status.kmod_ctx);
|
||||||
|
return (EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
diff --git src/module.c src/module.c
|
||||||
|
index f6d7144..aed2729 100644
|
||||||
|
--- src/module.c
|
||||||
|
+++ src/module.c
|
||||||
|
@@ -24,91 +24,151 @@
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
+#include <libkmod.h>
|
||||||
|
+#include <errno.h>
|
||||||
|
#include "module.h"
|
||||||
|
#include "bblogger.h"
|
||||||
|
#include "bbrun.h"
|
||||||
|
+#include "bbconfig.h"
|
||||||
|
+
|
||||||
|
+int module_unload_recursive(struct kmod_module *mod);
|
||||||
|
|
||||||
|
/**
|
||||||
|
- * Checks in /proc/modules whether a kernel module is loaded
|
||||||
|
+ * Checks whether a kernel module is loaded
|
||||||
|
*
|
||||||
|
* @param driver The name of the driver (not a filename)
|
||||||
|
* @return 1 if the module is loaded, 0 otherwise
|
||||||
|
*/
|
||||||
|
int module_is_loaded(char *driver) {
|
||||||
|
- // use the same buffer length as lsmod
|
||||||
|
- char buffer[4096];
|
||||||
|
- FILE * bbs = fopen("/proc/modules", "r");
|
||||||
|
- int ret = 0;
|
||||||
|
- /* assume mod_len <= sizeof(buffer) */
|
||||||
|
- int mod_len = strlen(driver);
|
||||||
|
-
|
||||||
|
- if (bbs == 0) {//error opening, return -1
|
||||||
|
- bb_log(LOG_DEBUG, "Couldn't open /proc/modules");
|
||||||
|
+ int err, state;
|
||||||
|
+ struct kmod_module *mod;
|
||||||
|
+
|
||||||
|
+ err = kmod_module_new_from_name(bb_status.kmod_ctx, driver, &mod);
|
||||||
|
+ if(err < 0) {
|
||||||
|
+ bb_log(LOG_DEBUG, "kmod_module_new_from_name(%s) failed.\n", driver);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
- while (fgets(buffer, sizeof(buffer), bbs)) {
|
||||||
|
- /* match "module" with "module " and not "module-blah" */
|
||||||
|
- if (!strncmp(buffer, driver, mod_len) && isspace(buffer[mod_len])) {
|
||||||
|
- /* module is found */
|
||||||
|
- ret = 1;
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- fclose(bbs);
|
||||||
|
- return ret;
|
||||||
|
+
|
||||||
|
+ state = kmod_module_get_initstate(mod);
|
||||||
|
+ kmod_module_unref(mod);
|
||||||
|
+
|
||||||
|
+ return state == KMOD_MODULE_LIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
- * Attempts to load a module. If the module has not been loaded after ten
|
||||||
|
- * seconds, give up
|
||||||
|
+ * Attempts to load a module.
|
||||||
|
*
|
||||||
|
* @param module_name The filename of the module to be loaded
|
||||||
|
* @param driver The name of the driver to be loaded
|
||||||
|
* @return 1 if the driver is succesfully loaded, 0 otherwise
|
||||||
|
*/
|
||||||
|
int module_load(char *module_name, char *driver) {
|
||||||
|
+ int err = 0;
|
||||||
|
+ int flags = KMOD_PROBE_IGNORE_LOADED;
|
||||||
|
+ struct kmod_list *l, *list = NULL;
|
||||||
|
+
|
||||||
|
if (module_is_loaded(driver) == 0) {
|
||||||
|
/* the module has not loaded yet, try to load it */
|
||||||
|
- bb_log(LOG_INFO, "Loading driver %s (module %s)\n", driver, module_name);
|
||||||
|
- char *mod_argv[] = {
|
||||||
|
- "modprobe",
|
||||||
|
- module_name,
|
||||||
|
- NULL
|
||||||
|
- };
|
||||||
|
- bb_run_fork_wait(mod_argv, 10);
|
||||||
|
- if (module_is_loaded(driver) == 0) {
|
||||||
|
- bb_log(LOG_ERR, "Module %s could not be loaded (timeout?)\n", module_name);
|
||||||
|
+
|
||||||
|
+ bb_log(LOG_INFO, "Loading driver '%s' (module '%s')\n", driver, module_name);
|
||||||
|
+ err = kmod_module_new_from_lookup(bb_status.kmod_ctx, module_name, &list);
|
||||||
|
+
|
||||||
|
+ if(err < 0) {
|
||||||
|
+ bb_log(LOG_DEBUG, "kmod_module_new_from_lookup(%s) failed (err: %d).\n",
|
||||||
|
+ module_name, err);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if(list == NULL) {
|
||||||
|
+ bb_log(LOG_ERR, "Module '%s' not found.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ kmod_list_foreach(l, list) {
|
||||||
|
+ struct kmod_module *mod = kmod_module_get_module(l);
|
||||||
|
+
|
||||||
|
+ bb_log(LOG_DEBUG, "Loading module '%s'.\n", kmod_module_get_name(mod));
|
||||||
|
+ err = kmod_module_probe_insert_module(mod, flags, NULL, NULL, NULL, 0);
|
||||||
|
+
|
||||||
|
+ if (err < 0) {
|
||||||
|
+ bb_log(LOG_DEBUG, "kmod_module_probe_insert_module(%s) failed (err: %d).\n",
|
||||||
|
+ kmod_module_get_name(mod), err);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ kmod_module_unref(mod);
|
||||||
|
+
|
||||||
|
+ if(err < 0) {
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ kmod_module_unref_list(list);
|
||||||
|
}
|
||||||
|
- return 1;
|
||||||
|
+
|
||||||
|
+ return err >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
- * Attempts to unload a module if loaded, for ten seconds before
|
||||||
|
- * giving up
|
||||||
|
+ * Unloads module and modules that are depending on this module.
|
||||||
|
+ *
|
||||||
|
+ * @param mod Reference to libkmod module
|
||||||
|
+ * @return 1 if the module is succesfully unloaded, 0 otherwise
|
||||||
|
+ */
|
||||||
|
+int module_unload_recursive(struct kmod_module *mod) {
|
||||||
|
+ int err = 0, flags = 0, refcnt;
|
||||||
|
+ struct kmod_list *holders;
|
||||||
|
+
|
||||||
|
+ holders = kmod_module_get_holders(mod);
|
||||||
|
+ if (holders != NULL) {
|
||||||
|
+ struct kmod_list *itr;
|
||||||
|
+
|
||||||
|
+ kmod_list_foreach(itr, holders) {
|
||||||
|
+ struct kmod_module *hm = kmod_module_get_module(itr);
|
||||||
|
+ err = module_unload_recursive(hm);
|
||||||
|
+ kmod_module_unref(hm);
|
||||||
|
+
|
||||||
|
+ if(err < 0) {
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ kmod_module_unref_list(holders);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ refcnt = kmod_module_get_refcnt(mod);
|
||||||
|
+ if(refcnt == 0) {
|
||||||
|
+ bb_log(LOG_INFO, "Unloading module %s\n", kmod_module_get_name(mod));
|
||||||
|
+ err = kmod_module_remove_module(mod, flags);
|
||||||
|
+ } else {
|
||||||
|
+ bb_log(LOG_ERR, "Failed to unload module '%s' (ref count: %d).\n",
|
||||||
|
+ kmod_module_get_name(mod), refcnt);
|
||||||
|
+ err = 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return err == 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * Attempts to unload a module if loaded.
|
||||||
|
*
|
||||||
|
* @param driver The name of the driver (not a filename)
|
||||||
|
* @return 1 if the driver is succesfully unloaded, 0 otherwise
|
||||||
|
*/
|
||||||
|
int module_unload(char *driver) {
|
||||||
|
+ int err;
|
||||||
|
+ struct kmod_module *mod;
|
||||||
|
if (module_is_loaded(driver) == 1) {
|
||||||
|
- int retries = 30;
|
||||||
|
- bb_log(LOG_INFO, "Unloading %s driver\n", driver);
|
||||||
|
- char *mod_argv[] = {
|
||||||
|
- "modprobe",
|
||||||
|
- "-r",
|
||||||
|
- driver,
|
||||||
|
- NULL
|
||||||
|
- };
|
||||||
|
- bb_run_fork_wait(mod_argv, 10);
|
||||||
|
- while (retries-- > 0 && module_is_loaded(driver) == 1) {
|
||||||
|
- usleep(100000);
|
||||||
|
- }
|
||||||
|
- if (module_is_loaded(driver) == 1) {
|
||||||
|
- bb_log(LOG_ERR, "Unloading %s driver timed out.\n", driver);
|
||||||
|
+ err = kmod_module_new_from_name(bb_status.kmod_ctx, driver, &mod);
|
||||||
|
+
|
||||||
|
+ if(err < 0) {
|
||||||
|
+ bb_log(LOG_DEBUG, "kmod_module_new_from_name(%s) failed (err: %d).\n",
|
||||||
|
+ driver, err);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ err = module_unload_recursive(mod);
|
||||||
|
+ kmod_module_unref(mod);
|
||||||
|
+
|
||||||
|
+ return err;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
@@ -120,18 +180,19 @@ int module_unload(char *driver) {
|
||||||
|
* @return 1 if the module is available for loading, 0 otherwise
|
||||||
|
*/
|
||||||
|
int module_is_available(char *module_name) {
|
||||||
|
- /* HACK to support call from optirun */
|
||||||
|
- char *modprobe_bin = "/sbin/modprobe";
|
||||||
|
- if (access(modprobe_bin, X_OK)) {
|
||||||
|
- /* if /sbin/modprobe is not found, pray that PATH contains it */
|
||||||
|
- modprobe_bin = "modprobe";
|
||||||
|
+ int err, available;
|
||||||
|
+ struct kmod_list *list = NULL;
|
||||||
|
+
|
||||||
|
+ err = kmod_module_new_from_lookup(bb_status.kmod_ctx, module_name, &list);
|
||||||
|
+
|
||||||
|
+ if(err < 0) {
|
||||||
|
+ bb_log(LOG_DEBUG, "kmod_module_new_from_lookup(%s) failed (err: %d).\n",
|
||||||
|
+ module_name, err);
|
||||||
|
}
|
||||||
|
- char *mod_argv[] = {
|
||||||
|
- modprobe_bin,
|
||||||
|
- "--dry-run",
|
||||||
|
- "--quiet",
|
||||||
|
- module_name,
|
||||||
|
- NULL
|
||||||
|
- };
|
||||||
|
- return bb_run_fork(mod_argv, 1) == EXIT_SUCCESS;
|
||||||
|
+
|
||||||
|
+ available = (err == 0) && list != NULL;
|
||||||
|
+
|
||||||
|
+ kmod_module_unref_list(list);
|
||||||
|
+
|
||||||
|
+ return available;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git Makefile.am Makefile.am
|
||||||
|
index 732e303..abcb4e9 100644
|
||||||
|
--- Makefile.am
|
||||||
|
+++ Makefile.am
|
||||||
|
@@ -49,7 +49,7 @@ sbin_PROGRAMS = bin/bumblebeed
|
||||||
|
bin_PROGRAMS = bin/optirun
|
||||||
|
|
||||||
|
bin_optirun_SOURCES = src/module.c src/bbconfig.c src/bblogger.c src/bbrun.c \
|
||||||
|
- src/bbsocket.c src/driver.c src/optirun.c src/bbsocketclient.c
|
||||||
|
+ src/bbsocket.c src/optirun.c src/bbsocketclient.c
|
||||||
|
bin_optirun_LDADD = ${glib_LIBS} ${kmod_LIBS} -lrt
|
||||||
|
bin_bumblebeed_SOURCES = src/pci.c src/bbconfig.c src/bblogger.c src/bbrun.c \
|
||||||
|
src/bbsocket.c src/module.c src/bbsecondary.c src/switch/switching.c \
|
||||||
|
diff --git src/optirun.c src/optirun.c
|
||||||
|
index a4607ea..643222c 100644
|
||||||
|
--- src/optirun.c
|
||||||
|
+++ src/optirun.c
|
||||||
|
@@ -37,7 +37,6 @@
|
||||||
|
#include "bbsocketclient.h"
|
||||||
|
#include "bblogger.h"
|
||||||
|
#include "bbrun.h"
|
||||||
|
-#include "driver.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
diff --git src/bumblebeed.c src/bumblebeed.c
|
||||||
|
index ef4a568..ac7a02d 100644
|
||||||
|
--- src/bumblebeed.c
|
||||||
|
+++ src/bumblebeed.c
|
||||||
|
@@ -503,8 +503,7 @@ int main(int argc, char* argv[]) {
|
||||||
|
config_dump();
|
||||||
|
|
||||||
|
// kmod context have to be available for config validation
|
||||||
|
- const char *null_cfg = NULL;
|
||||||
|
- bb_status.kmod_ctx = kmod_new(NULL, &null_cfg);
|
||||||
|
+ bb_status.kmod_ctx = kmod_new(NULL, NULL);
|
||||||
|
if (bb_status.kmod_ctx == NULL) {
|
||||||
|
bb_log(LOG_ERR, "kmod_new() failed!\n");
|
||||||
|
bb_closelog();
|
||||||
|
|
||||||
|
diff --git src/bumblebeed.c src/bumblebeed.c
|
||||||
|
index ac7a02d..688972d 100644
|
||||||
|
--- src/bumblebeed.c
|
||||||
|
+++ src/bumblebeed.c
|
||||||
|
@@ -461,6 +461,7 @@ int main(int argc, char* argv[]) {
|
||||||
|
/* first load the config to make the logging verbosity level available */
|
||||||
|
init_config();
|
||||||
|
bbconfig_parse_opts(argc, argv, PARSE_STAGE_PRECONF);
|
||||||
|
+ bbconfig_parse_opts(argc, argv, PARSE_STAGE_OTHER);
|
||||||
|
|
||||||
|
/* First look for an intel card */
|
||||||
|
struct pci_bus_id *pci_id_igd = pci_find_gfx_by_vendor(PCI_VENDOR_ID_INTEL, 0);
|
||||||
|
@@ -496,7 +497,6 @@ int main(int argc, char* argv[]) {
|
||||||
|
bbconfig_parse_conf_driver(bbcfg, bb_config.driver);
|
||||||
|
g_key_file_free(bbcfg);
|
||||||
|
}
|
||||||
|
- bbconfig_parse_opts(argc, argv, PARSE_STAGE_OTHER);
|
||||||
|
check_pm_method();
|
||||||
|
|
||||||
|
/* dump the config after detecting the driver */
|
||||||
|
|
||||||
|
diff --git src/module.c src/module.c
|
||||||
|
index aed2729..08f6f4a 100644
|
||||||
|
--- src/module.c
|
||||||
|
+++ src/module.c
|
||||||
|
@@ -45,8 +45,9 @@ int module_is_loaded(char *driver) {
|
||||||
|
|
||||||
|
err = kmod_module_new_from_name(bb_status.kmod_ctx, driver, &mod);
|
||||||
|
if(err < 0) {
|
||||||
|
- bb_log(LOG_DEBUG, "kmod_module_new_from_name(%s) failed.\n", driver);
|
||||||
|
- return -1;
|
||||||
|
+ bb_log(LOG_DEBUG, "kmod_module_new_from_name(%s) failed (err: %d).\n",
|
||||||
|
+ driver, err);
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
state = kmod_module_get_initstate(mod);
|
||||||
|
|
||||||
|
diff --git src/module.c src/module.c
|
||||||
|
index 08f6f4a..6a197dc 100644
|
||||||
|
--- src/module.c
|
||||||
|
+++ src/module.c
|
||||||
|
@@ -189,9 +189,10 @@ int module_is_available(char *module_name) {
|
||||||
|
if(err < 0) {
|
||||||
|
bb_log(LOG_DEBUG, "kmod_module_new_from_lookup(%s) failed (err: %d).\n",
|
||||||
|
module_name, err);
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- available = (err == 0) && list != NULL;
|
||||||
|
+ available = list != NULL;
|
||||||
|
|
||||||
|
kmod_module_unref_list(list);
|
||||||
|
|
||||||
|
|
||||||
|
diff --git src/bumblebeed.c src/bumblebeed.c
|
||||||
|
index 688972d..b1458ab 100644
|
||||||
|
--- src/bumblebeed.c
|
||||||
|
+++ src/bumblebeed.c
|
||||||
|
@@ -490,6 +490,14 @@ int main(int argc, char* argv[]) {
|
||||||
|
|
||||||
|
free(pci_id_igd);
|
||||||
|
|
||||||
|
+ // kmod context have to be available for driver detection
|
||||||
|
+ bb_status.kmod_ctx = kmod_new(NULL, NULL);
|
||||||
|
+ if (bb_status.kmod_ctx == NULL) {
|
||||||
|
+ bb_log(LOG_ERR, "kmod_new() failed!\n");
|
||||||
|
+ bb_closelog();
|
||||||
|
+ exit(EXIT_FAILURE);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
GKeyFile *bbcfg = bbconfig_parse_conf();
|
||||||
|
bbconfig_parse_opts(argc, argv, PARSE_STAGE_DRIVER);
|
||||||
|
driver_detect();
|
||||||
|
@@ -502,14 +510,6 @@ int main(int argc, char* argv[]) {
|
||||||
|
/* dump the config after detecting the driver */
|
||||||
|
config_dump();
|
||||||
|
|
||||||
|
- // kmod context have to be available for config validation
|
||||||
|
- bb_status.kmod_ctx = kmod_new(NULL, NULL);
|
||||||
|
- if (bb_status.kmod_ctx == NULL) {
|
||||||
|
- bb_log(LOG_ERR, "kmod_new() failed!\n");
|
||||||
|
- bb_closelog();
|
||||||
|
- exit(EXIT_FAILURE);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
if (config_validate() != 0) {
|
||||||
|
return (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git src/module.c src/module.c
|
||||||
|
index 6a197dc..cdc4a9b 100644
|
||||||
|
--- src/module.c
|
||||||
|
+++ src/module.c
|
||||||
|
@@ -81,7 +81,7 @@ int module_load(char *module_name, char *driver) {
|
||||||
|
}
|
||||||
|
|
||||||
|
if(list == NULL) {
|
||||||
|
- bb_log(LOG_ERR, "Module '%s' not found.\n");
|
||||||
|
+ bb_log(LOG_ERR, "Module '%s' not found.\n", module_name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
diff --git src/bblogger.c src/bblogger.c
|
||||||
|
index 804e5b8..caff8a8 100644
|
||||||
|
--- src/bblogger.c
|
||||||
|
+++ src/bblogger.c
|
||||||
|
@@ -228,7 +228,7 @@ void check_xorg_pipe(void){
|
||||||
|
/* line / buffer is full, process the remaining buffer the next round */
|
||||||
|
repeat = 1;
|
||||||
|
}
|
||||||
|
- }else{
|
||||||
|
+ } else {
|
||||||
|
if (r == 0 || (errno != EAGAIN && r == -1)){
|
||||||
|
/* the pipe is closed/invalid. Clean up. */
|
||||||
|
if (bb_status.x_pipe[0] != -1){close(bb_status.x_pipe[0]); bb_status.x_pipe[0] = -1;}
|
||||||
|
@@ -257,5 +257,5 @@ void check_xorg_pipe(void){
|
||||||
|
memmove(x_output_buffer, next_part, x_buffer_pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- }while(repeat);
|
||||||
|
+ }while (repeat);
|
||||||
|
}/* check_xorg_pipe */
|
||||||
|
diff --git src/module.c src/module.c
|
||||||
|
index cdc4a9b..c378bd7 100644
|
||||||
|
--- src/module.c
|
||||||
|
+++ src/module.c
|
||||||
|
@@ -44,7 +44,7 @@ int module_is_loaded(char *driver) {
|
||||||
|
struct kmod_module *mod;
|
||||||
|
|
||||||
|
err = kmod_module_new_from_name(bb_status.kmod_ctx, driver, &mod);
|
||||||
|
- if(err < 0) {
|
||||||
|
+ if (err < 0) {
|
||||||
|
bb_log(LOG_DEBUG, "kmod_module_new_from_name(%s) failed (err: %d).\n",
|
||||||
|
driver, err);
|
||||||
|
return 0;
|
||||||
|
@@ -74,13 +74,13 @@ int module_load(char *module_name, char *driver) {
|
||||||
|
bb_log(LOG_INFO, "Loading driver '%s' (module '%s')\n", driver, module_name);
|
||||||
|
err = kmod_module_new_from_lookup(bb_status.kmod_ctx, module_name, &list);
|
||||||
|
|
||||||
|
- if(err < 0) {
|
||||||
|
+ if (err < 0) {
|
||||||
|
bb_log(LOG_DEBUG, "kmod_module_new_from_lookup(%s) failed (err: %d).\n",
|
||||||
|
module_name, err);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if(list == NULL) {
|
||||||
|
+ if (list == NULL) {
|
||||||
|
bb_log(LOG_ERR, "Module '%s' not found.\n", module_name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -98,7 +98,7 @@ int module_load(char *module_name, char *driver) {
|
||||||
|
|
||||||
|
kmod_module_unref(mod);
|
||||||
|
|
||||||
|
- if(err < 0) {
|
||||||
|
+ if (err < 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -128,7 +128,7 @@ int module_unload_recursive(struct kmod_module *mod) {
|
||||||
|
err = module_unload_recursive(hm);
|
||||||
|
kmod_module_unref(hm);
|
||||||
|
|
||||||
|
- if(err < 0) {
|
||||||
|
+ if (err < 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -136,7 +136,7 @@ int module_unload_recursive(struct kmod_module *mod) {
|
||||||
|
}
|
||||||
|
|
||||||
|
refcnt = kmod_module_get_refcnt(mod);
|
||||||
|
- if(refcnt == 0) {
|
||||||
|
+ if (refcnt == 0) {
|
||||||
|
bb_log(LOG_INFO, "Unloading module %s\n", kmod_module_get_name(mod));
|
||||||
|
err = kmod_module_remove_module(mod, flags);
|
||||||
|
} else {
|
||||||
|
@@ -160,7 +160,7 @@ int module_unload(char *driver) {
|
||||||
|
if (module_is_loaded(driver) == 1) {
|
||||||
|
err = kmod_module_new_from_name(bb_status.kmod_ctx, driver, &mod);
|
||||||
|
|
||||||
|
- if(err < 0) {
|
||||||
|
+ if (err < 0) {
|
||||||
|
bb_log(LOG_DEBUG, "kmod_module_new_from_name(%s) failed (err: %d).\n",
|
||||||
|
driver, err);
|
||||||
|
return 0;
|
||||||
|
@@ -186,7 +186,7 @@ int module_is_available(char *module_name) {
|
||||||
|
|
||||||
|
err = kmod_module_new_from_lookup(bb_status.kmod_ctx, module_name, &list);
|
||||||
|
|
||||||
|
- if(err < 0) {
|
||||||
|
+ if (err < 0) {
|
||||||
|
bb_log(LOG_DEBUG, "kmod_module_new_from_lookup(%s) failed (err: %d).\n",
|
||||||
|
module_name, err);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
diff --git src/bbconfig.c src/bbconfig.c
|
||||||
|
index 1dff5e0..af38098 100644
|
||||||
|
--- src/bbconfig.c
|
||||||
|
+++ src/bbconfig.c
|
||||||
|
@@ -251,12 +251,6 @@ Bumblebee homepage: <http://Bumblebee-Project.org/>\n", out);
|
||||||
|
*/
|
||||||
|
static int bbconfig_parse_common(int opt, char *value) {
|
||||||
|
switch (opt) {
|
||||||
|
- case 'q'://quiet mode
|
||||||
|
- bb_status.verbosity = VERB_NONE;
|
||||||
|
- break;
|
||||||
|
- case OPT_DEBUG://debug mode
|
||||||
|
- bb_status.verbosity = VERB_ALL;
|
||||||
|
- break;
|
||||||
|
case 'd'://X display number
|
||||||
|
set_string_value(&bb_config.x_display, value);
|
||||||
|
break;
|
||||||
|
@@ -307,6 +301,12 @@ void bbconfig_parse_opts(int argc, char *argv[], int conf_round) {
|
||||||
|
bb_status.verbosity++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
+ case 'q'://quiet mode
|
||||||
|
+ bb_status.verbosity = VERB_NONE;
|
||||||
|
+ break;
|
||||||
|
+ case OPT_DEBUG://debug mode
|
||||||
|
+ bb_status.verbosity = VERB_ALL;
|
||||||
|
+ break;
|
||||||
|
case 's': /* Unix socket to use for communication */
|
||||||
|
set_string_value(&bb_config.socket_path, optarg);
|
||||||
|
break;
|
||||||
|
diff --git src/bumblebeed.c src/bumblebeed.c
|
||||||
|
index b1458ab..6e0ade5 100644
|
||||||
|
--- src/bumblebeed.c
|
||||||
|
+++ src/bumblebeed.c
|
||||||
|
@@ -461,7 +461,6 @@ int main(int argc, char* argv[]) {
|
||||||
|
/* first load the config to make the logging verbosity level available */
|
||||||
|
init_config();
|
||||||
|
bbconfig_parse_opts(argc, argv, PARSE_STAGE_PRECONF);
|
||||||
|
- bbconfig_parse_opts(argc, argv, PARSE_STAGE_OTHER);
|
||||||
|
|
||||||
|
/* First look for an intel card */
|
||||||
|
struct pci_bus_id *pci_id_igd = pci_find_gfx_by_vendor(PCI_VENDOR_ID_INTEL, 0);
|
||||||
|
@@ -505,6 +504,7 @@ int main(int argc, char* argv[]) {
|
||||||
|
bbconfig_parse_conf_driver(bbcfg, bb_config.driver);
|
||||||
|
g_key_file_free(bbcfg);
|
||||||
|
}
|
||||||
|
+ bbconfig_parse_opts(argc, argv, PARSE_STAGE_OTHER);
|
||||||
|
check_pm_method();
|
||||||
|
|
||||||
|
/* dump the config after detecting the driver */
|
|
@ -1,34 +0,0 @@
|
||||||
https://github.com/Bumblebee-Project/Bumblebee/issues/565#issuecomment-62546098
|
|
||||||
|
|
||||||
diff --git src/bbsecondary.c src/bbsecondary.c
|
|
||||||
index 6b635ee..7885aa5 100644
|
|
||||||
--- src/bbsecondary.c
|
|
||||||
+++ src/bbsecondary.c
|
|
||||||
@@ -119,6 +119,17 @@ static bool switch_and_load(void)
|
|
||||||
if (!module_load(module_name, driver_name)) {
|
|
||||||
set_bb_error("Could not load GPU driver");
|
|
||||||
return false;
|
|
||||||
+ } else {
|
|
||||||
+ /* XXX NVIDIA UVM support */
|
|
||||||
+ if (strstr(module_name, "nvidia")) { /* We are using NVIDIA's proprietary driver */
|
|
||||||
+ char uvm_module_name[1024];
|
|
||||||
+ sprintf(uvm_module_name, "%s-uvm", module_name);
|
|
||||||
+ if (!module_load(uvm_module_name, "nvidia_uvm")) {
|
|
||||||
+ char log_string[1024];
|
|
||||||
+ sprintf(log_string, "Cannot load UVM module: %s\n", uvm_module_name);
|
|
||||||
+ bb_log(LOG_ERR, log_string);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
@@ -232,6 +243,10 @@ static void switch_and_unload(void)
|
|
||||||
}
|
|
||||||
/* unload the driver loaded by the graphica card */
|
|
||||||
if (pci_get_driver(driver, pci_bus_id_discrete, sizeof driver)) {
|
|
||||||
+ /* XXX NVIDIA UVM support */
|
|
||||||
+ if (strstr(driver, "nvidia")) {
|
|
||||||
+ module_unload("nvidia_uvm");
|
|
||||||
+ }
|
|
||||||
module_unload(driver);
|
|
||||||
}
|
|
|
@ -1,7 +1,7 @@
|
||||||
# Template file for 'bumblebee'
|
# Template file for 'bumblebee'
|
||||||
pkgname=bumblebee
|
pkgname=bumblebee
|
||||||
version=3.2.1
|
version=3.2.1
|
||||||
revision=6
|
revision=7
|
||||||
only_for_archs="i686 x86_64"
|
only_for_archs="i686 x86_64"
|
||||||
build_style=gnu-configure
|
build_style=gnu-configure
|
||||||
configure_args="
|
configure_args="
|
||||||
|
@ -10,20 +10,24 @@ configure_args="
|
||||||
CONF_MODPATH_NVIDIA=/usr/lib/xorg/modules
|
CONF_MODPATH_NVIDIA=/usr/lib/xorg/modules
|
||||||
--with-udev-rules=/usr/lib/udev/rules.d/
|
--with-udev-rules=/usr/lib/udev/rules.d/
|
||||||
--without-pidfile"
|
--without-pidfile"
|
||||||
hostmakedepends="pkg-config help2man"
|
|
||||||
makedepends="VirtualGL-devel glib-devel MesaLib-devel"
|
|
||||||
depends="VirtualGL"
|
|
||||||
conf_files="
|
conf_files="
|
||||||
/etc/bumblebee/bumblebee.conf
|
/etc/bumblebee/bumblebee.conf
|
||||||
/etc/bumblebee/xorg.conf.nouveau
|
/etc/bumblebee/xorg.conf.nouveau
|
||||||
/etc/bumblebee/xorg.conf.nvidia"
|
/etc/bumblebee/xorg.conf.nvidia"
|
||||||
system_groups="bumblebee"
|
hostmakedepends="automake autoconf-archive pkg-config help2man"
|
||||||
|
makedepends="VirtualGL-devel glib-devel MesaLib-devel libkmod-devel"
|
||||||
|
depends="VirtualGL"
|
||||||
short_desc="NVIDIA Optimus support for Linux through VirtualGL"
|
short_desc="NVIDIA Optimus support for Linux through VirtualGL"
|
||||||
maintainer="Juan RP <xtraeme@voidlinux.org>"
|
maintainer="Juan RP <xtraeme@voidlinux.org>"
|
||||||
|
license="GPL-3.0-or-later"
|
||||||
homepage="http://www.bumblebee-project.org/"
|
homepage="http://www.bumblebee-project.org/"
|
||||||
license="GPL-3"
|
|
||||||
distfiles="http://www.bumblebee-project.org/${pkgname}-${version}.tar.gz"
|
distfiles="http://www.bumblebee-project.org/${pkgname}-${version}.tar.gz"
|
||||||
checksum=1018703b07e2f607a4641249d69478ce076ae5a1e9dd6cff5694d394fa7ee30e
|
checksum=1018703b07e2f607a4641249d69478ce076ae5a1e9dd6cff5694d394fa7ee30e
|
||||||
|
system_groups="bumblebee"
|
||||||
|
|
||||||
|
pre_configure() {
|
||||||
|
autoreconf -fi
|
||||||
|
}
|
||||||
|
|
||||||
post_install() {
|
post_install() {
|
||||||
vsv bumblebeed
|
vsv bumblebeed
|
||||||
|
|
Loading…
Reference in New Issue