Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,12 @@ 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/driver.c src/optirun.c src/bbsocketclient.c src/findpathwild.c
bin_optirun_LDADD = ${glib_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
src/driver.c src/bumblebeed.c src/findpathwild.c
bin_bumblebeed_LDADD = ${x11_LIBS} ${libbsd_LIBS} ${glib_LIBS} -lrt

dist_doc_DATA = $(relnotes) README.markdown
Expand Down
33 changes: 28 additions & 5 deletions src/bbconfig.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
/*
* Copyright (c) 2017, The Bumblebee Project
* Author: Stefan Helmert (TheTesla) <stefan.helmert@t-online.de>
*
* Copyright (c) 2011-2013, The Bumblebee Project
* Author: Joaquín Ignacio Aramendía samsagax@gmail.com
* Author: Jaron Viëtor AKA "Thulinma" <jaron@vietors.com>
Expand Down Expand Up @@ -34,6 +37,7 @@
#include "bbconfig.h"
#include "bblogger.h"
#include "module.h"
#include "findpathwild.h"

/* config values for PM methods, edit bb_pm_method in bbconfig.h as well! */
const char *bb_pm_method_string[PM_METHODS_COUNT] = {
Expand Down Expand Up @@ -380,7 +384,10 @@ GKeyFile *bbconfig_parse_conf(void) {
}
key = "PrimusLibraryPath";
if (g_key_file_has_key(bbcfg, section, key, NULL)) {
free_and_set_value(&bb_config.primus_ld_path, g_key_file_get_string(bbcfg, section, key, NULL));
char* primusLibraryPath;
primusLibraryPath = malloc(MAX_STR_LEN);
findPathListWild(primusLibraryPath, g_key_file_get_string(bbcfg, section, key, NULL));
free_and_set_value(&bb_config.primus_ld_path, primusLibraryPath);
}
key = "VGLTransport";
if (g_key_file_has_key(bbcfg, section, key, NULL)) {
Expand Down Expand Up @@ -423,7 +430,10 @@ GKeyFile *bbconfig_parse_conf(void) {
}
key = "XorgConfDir";
if (g_key_file_has_key(bbcfg, section, key, NULL)) {
free_and_set_value(&bb_config.x_conf_dir, g_key_file_get_string(bbcfg, section, key, NULL));
char* xorgConfDir;
xorgConfDir = malloc(MAX_STR_LEN);
findPathListWild(xorgConfDir, g_key_file_get_string(bbcfg, section, key, NULL));
free_and_set_value(&bb_config.x_conf_dir, xorgConfDir);
}
return bbcfg;
}
Expand Down Expand Up @@ -453,18 +463,31 @@ void bbconfig_parse_conf_driver(GKeyFile *bbcfg, char *driver) {
/* if KernelDriver is empty, the default behavior is to copy Driver which
* is done in driver_detect() */
if (*module_name) {
free_and_set_value(&bb_config.module_name, module_name);
char* kernelDriver;
kernelDriver = malloc(MAX_STR_LEN);
if(findDriverWild(kernelDriver, module_name)) {
free_and_set_value(&bb_config.module_name, kernelDriver);
} else {
free_and_set_value(&bb_config.module_name, module_name);
}
} else {
g_free(module_name);
}
}
key = "LibraryPath";
if (g_key_file_has_key(bbcfg, section, key, NULL)) {
free_and_set_value(&bb_config.ld_path, g_key_file_get_string(bbcfg, section, key, NULL));
char* libraryPath;
libraryPath = malloc(MAX_STR_LEN);
findPathListWild(libraryPath, g_key_file_get_string(bbcfg, section, key, NULL));
free_and_set_value(&bb_config.ld_path, libraryPath);

}
key = "XorgModulePath";
if (g_key_file_has_key(bbcfg, section, key, NULL)) {
free_and_set_value(&bb_config.mod_path, g_key_file_get_string(bbcfg, section, key, NULL));
char* xorgModulePath;
xorgModulePath = malloc(MAX_STR_LEN);
findPathListWildDelim(xorgModulePath, g_key_file_get_string(bbcfg, section, key, NULL), ',');
free_and_set_value(&bb_config.mod_path, xorgModulePath);
}
key = "PMMethod";
if (g_key_file_has_key(bbcfg, section, key, NULL)) {
Expand Down
203 changes: 203 additions & 0 deletions src/findpathwild.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
/***********************************************************************

Copyright (c) 2017 Stefan Helmert <stefan.helmert@t-online.de>

***********************************************************************/

#include "findpathwild.h"
#include <dirent.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <libgen.h>
#include <sys/utsname.h>


char* getRootPath(char *rootPath, char *wildPath)
{
char c;
c = 1;
unsigned pidxend = 0;
for(int i=0; c && i < MAX_STR_LEN; i++){
c = wildPath[i];
rootPath[i] = c;
if('/' == c){
pidxend = i;
}
if('?' == c){
rootPath[pidxend] = 0;
return &wildPath[pidxend+1]; // may be dangerous, bacause reduces maximum string length
}
}
return "";
}

char* splitStr(char* str, char delim)
{
char c;
c = 1;
for(int i=0; c && i < MAX_STR_LEN; i++){
c = str[i];
if(delim == c){
str[i] = 0;
return &str[i+1];
}

}
return "";
}

int cmpStrWild(char* inputStr, char* wildStr)
{
char ci, cw;
ci = 1;
cw = 1;
for(int i = 0; ci && cw && i < MAX_STR_LEN; i++){
ci = inputStr[i];
cw = wildStr[i];
if(ci == cw) continue;
if('?' == cw) continue;
return 0;
}
if(0 == ci && 0 == cw) return 1;
return 0;
}

char* findPathWild(char* foundPath, char* wildPath)
{
DIR *dir;
struct dirent *ent;
char found[MAX_STR_LEN];
char rootPath[MAX_STR_LEN];
char currentLabel[MAX_STR_LEN];
char* pathEnd;
int cmpResult;


if('/' == wildPath[strlen(wildPath) -1]){
wildPath[strlen(wildPath) -1] = 0;
}

pathEnd = getRootPath(rootPath, wildPath);
strncpy(currentLabel, pathEnd, MAX_STR_LEN - 1);
pathEnd = splitStr(currentLabel, '/');
strncat(rootPath, "/", MAX_STR_LEN - strlen(rootPath) - 1);
// structur: /root/Path / currentLabel / p?th/E?d/
// | rootPath | currentLabel | pathEnd

if ((dir = opendir (rootPath)) != NULL) { // acceppt only if path exists
if(0 == currentLabel[0]) { // no currentLabel means end of path reached
strncpy(foundPath, rootPath, MAX_STR_LEN - 1);
closedir (dir);
return foundPath; // means the path is found in deepest recursion
}
while ((ent = readdir (dir)) != NULL) { // go through all dirs in rootPath
cmpResult = cmpStrWild(ent->d_name, currentLabel); // check if wildcard matches
if(cmpResult) { // found match - next recursion step, process inner directory wildcards
strncpy(found, rootPath, MAX_STR_LEN - 1);
strncat(found, ent->d_name, MAX_STR_LEN - strlen(found) - 1);
strncat(found, "/", MAX_STR_LEN - strlen(found) - 1);
strncat(found, pathEnd, MAX_STR_LEN - strlen(found) - 1);
if(findPathWild(foundPath, found) != NULL) {
closedir (dir);
return foundPath;
}
}
}
closedir (dir);
return NULL;
} else {
return NULL;
}
}


char* findPathListWildDelim(char* foundPathList, char* wildPathList, char delim)
{
char lWildPathList[MAX_STR_LEN] = "";
char foundPath[MAX_STR_LEN] = "";
char* nextStr;
char* wildPath;
char delimStr[2];
delimStr[0] = delim;
delimStr[1] = 0;
foundPathList[0] = 0;
strncpy(lWildPathList, wildPathList, MAX_STR_LEN - 1);
wildPath = lWildPathList;
while(1){
nextStr = splitStr(wildPath, delim);

if(0 == wildPath[0]) {
return foundPathList;
}

if(findPathWild(foundPath, wildPath)){
if(0 != foundPathList[0]) {
strncat(foundPathList, delimStr, MAX_STR_LEN - strlen(foundPathList) - 1);
}
strncat(foundPathList, foundPath, MAX_STR_LEN - strlen(foundPathList) - 1);
}
wildPath = nextStr;
}
return NULL;
}

char* findPathListWild(char* foundPathList, char* wildPathList)
{
return findPathListWildDelim(foundPathList, wildPathList, ':');
}

char* findFileWild(char* foundDriver, char* fileNameWild, char* rootPath)
{
DIR *dir;
struct dirent *ent;
char recursePath[MAX_STR_LEN];
char* ret;
if ((dir = opendir (rootPath)) != NULL) {
while ((ent = readdir (dir)) != NULL) {
if(0 == strcmp(ent->d_name, ".")) continue;
if(0 == strcmp(ent->d_name, "..")) continue;
strncpy(recursePath, rootPath, MAX_STR_LEN - 1);
strncat(recursePath, "/", MAX_STR_LEN - strlen(recursePath) - 1);
strncat(recursePath, ent->d_name, MAX_STR_LEN - strlen(recursePath) - 1);
if(NULL != (ret = findFileWild(foundDriver, fileNameWild, recursePath))) {
return ret;
}

}
closedir (dir);
return NULL;
} else { // can't open dir (is file or dir has not the right permissions)
struct stat s;
stat(rootPath, &s);
if(S_ISREG(s.st_mode)) { // is a file
if(cmpStrWild(basename(rootPath), fileNameWild)) {
strncpy(foundDriver, basename(rootPath), MAX_STR_LEN - 1);
return rootPath;
}
}
return NULL;
}
}

char* findDriverWild(char* foundDriver, char* driverNameWild)
{
struct utsname unameData;
char rootPath[MAX_STR_LEN];
char wild[MAX_STR_LEN];
char* ret;
if(uname(&unameData)) {
return NULL;
}
strncpy(rootPath, "/lib/modules/", MAX_STR_LEN - 1);
strncat(rootPath, unameData.release, MAX_STR_LEN - strlen(rootPath) - 1);
strncpy(wild, driverNameWild, MAX_STR_LEN - 1);
strncat(wild, ".ko", MAX_STR_LEN - strlen(wild) - 1);
ret = findFileWild(foundDriver, wild, rootPath);
foundDriver[strlen(foundDriver) - 3] = 0;
return ret;
}



22 changes: 22 additions & 0 deletions src/findpathwild.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/***********************************************************************

Copyright (c) 2017 Stefan Helmert <stefan.helmert@t-online.de>

***********************************************************************/


#define MAX_STR_LEN 512

char* getRootPath(char *rootPath, char *wildPath);
char* splitStr(char* str, char delim);
int cmpStrWild(char* inputStr, char* wildStr);
char* findPathWild(char* foundPath, char* wildPath);
char* findPathListWildDelim(char* foundPathList, char* wildPathList, char delim);
char* findPathListWild(char* foundPathList, char* wildPathList);
char* findFileWild(char* foundDriver, char* fileNameWild, char* rootPath);
char* findDriverWild(char* foundDriver, char* driverNameWild);





69 changes: 69 additions & 0 deletions test/bumblebee.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Configuration file for Bumblebee. Values should **not** be put between quotes

## Server options. Any change made in this section will need a server restart
# to take effect.
[bumblebeed]
# The secondary Xorg server DISPLAY number
VirtualDisplay=:8
# Should the unused Xorg server be kept running? Set this to true if waiting
# for X to be ready is too long and don't need power management at all.
KeepUnusedXServer=false
# The name of the Bumbleblee server group name (GID name)
ServerGroup=bumblebee
# Card power state at exit. Set to false if the card shoud be ON when Bumblebee
# server exits.
TurnCardOffAtExit=false
# The default behavior of '-f' option on optirun. If set to "true", '-f' will
# be ignored.
NoEcoModeOverride=false
# The Driver used by Bumblebee server. If this value is not set (or empty),
# auto-detection is performed. The available drivers are nvidia and nouveau
# (See also the driver-specific sections below)
Driver = nvidia
# Directory with a dummy config file to pass as a -configdir to secondary X
XorgConfDir=/etc/bumblebee/xorg.conf.d

## Client options. Will take effect on the next optirun executed.
[optirun]
# Acceleration/ rendering bridge, possible values are auto, virtualgl and
# primus.
Bridge=auto
# The method used for VirtualGL to transport frames between X servers.
# Possible values are proxy, jpeg, rgb, xv and yuv.
VGLTransport=proxy
# List of paths which are searched for the primus libGL.so.1 when using
# the primus bridge
PrimusLibraryPath=/usr/lib/x86_64-linux-gnu/primus:/usr/lib/i386-linux-gnu/primus
# Should the program run under optirun even if Bumblebee server or nvidia card
# is not available?
AllowFallbackToIGC=false


# Driver-specific settings are grouped under [driver-NAME]. The sections are
# parsed if the Driver setting in [bumblebeed] is set to NAME (or if auto-
# detection resolves to NAME).
# PMMethod: method to use for saving power by disabling the nvidia card, valid
# values are: auto - automatically detect which PM method to use
# bbswitch - new in BB 3, recommended if available
# switcheroo - vga_switcheroo method, use at your own risk
# none - disable PM completely
# https://github.com/Bumblebee-Project/Bumblebee/wiki/Comparison-of-PM-methods

## Section with nvidia driver specific options, only parsed if Driver=nvidia
[driver-nvidia]
# Module name to load, defaults to Driver if empty or unset
KernelDriver = nvidia_???
PMMethod=auto
# colon-separated path to the nvidia libraries
LibraryPath = /usr/lib/nvidia-???:/usr/lib32/nvidia-???
# comma-separated path of the directory containing nvidia_drv.so and the
# default Xorg modules path
XorgModulePath = /usr/lib/nvidia-???/xorg,/usr/lib/xorg/modules
XorgConfFile=/etc/bumblebee/xorg.conf.nvidia

## Section with nouveau driver specific options, only parsed if Driver=nouveau
[driver-nouveau]
KernelDriver=nouveau
PMMethod=auto
XorgConfFile=/etc/bumblebee/xorg.conf.nouveau