Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor script to be sudoers-friendly #87

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
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
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,16 @@ It started with a revelation that bumblebee in current state offers very poor pe
1. run `nvidia-xrun [app]`
1. enjoy

Currently sudo is required as the script needs to wake up GPU, modprobe the nvidia driver and perform cleanup afterwards. For this we use bbswitch.
### Passwordless `sudo`
Whitelisting `nvidia-toggle` in your sudoer's file allows you to use `nvidia-xrun` without entering your password:

```
%users ALL=(root) NOPASSWD:/usr/bin/nvidia-toggle
```

...where `/usr/bin/nvidia-toggle` is the full path to the `nvidia-toggle` script.

Note: it is a good practice to ensure binaries/scripts/etc. that are whitelisted for passwordless `sudo` are owned by root.

## Structure
* **nvidia-xrun** - uses following dir structure:
Expand Down
82 changes: 82 additions & 0 deletions nvidia-toggle
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#!/bin/bash
# nvidia-toggle [-d] (on | off)

DRY_RUN=0
if [[ $EUID -ne 0 ]]; then
(>&2 echo "This script must be run as root")
exit 1
fi

function execute {
if [ ${DRY_RUN} -eq 1 ]
then
echo ">>Dry run. Command: $*"
else
eval $*
fi
}

function die {
(>&2 echo $@)
exit 1
}

if [ "$1" == "-d" ]
then
DRY_RUN=1
shift 1
fi

case $1 in
on)
# --------- TURNING ON GPU -----------
echo 'Waking up nvidia GPU'
if ! [ -f /proc/acpi/bbswitch ]
then
execute "modprobe bbswitch" || die "Can't modprobe bbswitch"
fi
execute "tee /proc/acpi/bbswitch <<<ON" || die "Can't turn bbswitch on"

# ---------- LOADING MODULES ----------
echo 'Loading nvidia module'
execute "modprobe nvidia" || die "Can't modprobe nvidia"

echo 'Loading nvidia_uvm module'
execute "modprobe nvidia_uvm" || die "Can't modprove nvidia_uvm"

echo 'Loading nvidia_modeset module'
execute "modprobe nvidia_modeset" || die "Can't modprobe nvidia_modeset"

echo 'Loading nvidia_drm module'
execute "modprobe nvidia_drm" || die "Can't modprobe nvidia_drm"
;;
off)
# ---------- UNLOADING MODULES --------
echo 'Unloading nvidia_drm module'
execute "rmmod nvidia_drm" || die "Can't rmmod nvidia_drm"

echo 'Unloading nvidia_modeset module'
execute "rmmod nvidia_modeset" || die "Can't rmmod nvidia_modeset"

echo 'Unloading nvidia_uvm module'
execute "rmmod nvidia_uvm" || die "Can't rmmod nvidia_uvm"

echo 'Unloading nvidia module'
execute "rmmod nvidia" || die "Can't rmmod nvidia"

# --------- TURNING OFF GPU ----------
if [ -f /proc/acpi/bbswitch ]
then
echo 'Turning off nvidia GPU'
execute "tee /proc/acpi/bbswitch <<<OFF" || die "Can't turn bbswitch off"

echo -n 'Current state of nvidia GPU: '
execute "cat /proc/acpi/bbswitch"
else
echo "Bbswitch kernel module not loaded."
fi
;;
*)
die "nvidia-toggle [-d] (on | off)"
;;
esac
54 changes: 10 additions & 44 deletions nvidia-xrun
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ function execute {
fi
}

function die {
(>&2 echo $@)
exit 1
}

if [[ $EUID -eq 0 ]]; then
echo "This script must not be run as root" >&2
Expand Down Expand Up @@ -69,51 +73,13 @@ EXECL="/etc/X11/xinit/nvidia-xinitrc $EXECL"

COMMAND="xinit $EXECL -- $NEWDISP vt$LVT -nolisten tcp -br -config nvidia-xorg.conf -configdir nvidia-xorg.conf.d"

# --------- TURNING ON GPU -----------
echo 'Waking up nvidia GPU'
if ! [ -f /proc/acpi/bbswitch ]
then
execute "sudo modprobe bbswitch"
fi
execute "sudo tee /proc/acpi/bbswitch <<<ON"

# ---------- LOADING MODULES ----------
echo 'Loading nvidia module'
execute "sudo modprobe nvidia"

echo 'Loading nvidia_uvm module'
execute "sudo modprobe nvidia_uvm"

echo 'Loading nvidia_modeset module'
execute "sudo modprobe nvidia_modeset"

echo 'Loading nvidia_drm module'
execute "sudo modprobe nvidia_drm"
# ---------- TURNING ON GPU -----------
echo 'Loading nvidia'
execute "sudo nvidia-toggle on" || die "Could not load nvidia"

# ---------- EXECUTING COMMAND --------
execute ${COMMAND}

# ---------- UNLOADING MODULES --------
echo 'Unloading nvidia_drm module'
execute "sudo rmmod nvidia_drm"

echo 'Unloading nvidia_modeset module'
execute "sudo rmmod nvidia_modeset"

echo 'Unloading nvidia_uvm module'
execute "sudo rmmod nvidia_uvm"

echo 'Unloading nvidia module'
execute "sudo rmmod nvidia"
execute ${COMMAND} || die "Could not execute command"

# --------- TURNING OFF GPU ----------
if [ -f /proc/acpi/bbswitch ]
then
echo 'Turning off nvidia GPU'
execute "sudo tee /proc/acpi/bbswitch <<<OFF"

echo -n 'Current state of nvidia GPU: '
execute "cat /proc/acpi/bbswitch"
else
echo "Bbswitch kernel module not loaded."
fi
echo 'Unloading nvidia'
execute "sudo nvidia-toggle off" || die "Could not unload nvidia"
2 changes: 2 additions & 0 deletions rpm-spec/nvidia-xrun.spec
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ License: GNU GPL V2
Source0: nvidia-xrun
Source1: nvidia-xorg.conf
Source2: nvidia-xinitrc
Source3: nvidia-toggle
buildroot: %{_tmppath}/%{name}-root
BuildArch: noarch
%description
Expand All @@ -22,6 +23,7 @@ install -pm 755 %{SOURCE2} %{buildroot}/%{_sysconfdir}/X11/xinit/

%files
%{_bindir}/nvidia-xrun
%{_bindir}/nvidia-toggle
%{_sysconfdir}/X11/nvidia-xorg.conf
%{_sysconfdir}/X11/xinit
%{_sysconfdir}/X11/xinit/nvidia-xinitrc
Expand Down