Skip to content
This repository was archived by the owner on May 3, 2026. It is now read-only.

Commit d5df344

Browse files
committed
fix: prevent GPU-not-found crash when switching to hybrid mode
Two related bugs caused envycontrol to crash with 'Could not find Nvidia GPU' even when switching to a mode that doesn't need the GPU visible: 1. get_current_mode() required BOTH the blacklist file AND the udev removal rule to report 'integrated'. If only the udev rule existed (e.g. after a partial or interrupted previous switch), the function returned 'hybrid', misleading the CachedConfig adapter. Fix: any single EnvyControl-specific integrated-mode file is now sufficient to report integrated mode, since all three paths (/etc/modprobe.d/blacklist-nvidia.conf, /etc/udev/rules.d/50-remove-nvidia.rules, /lib/udev/rules.d/50-remove-nvidia.rules) are written exclusively by envycontrol for that mode. 2. CachedConfig.adapter() called create_cache_file() whenever the current mode was detected as hybrid, including when the requested switch target was also hybrid. create_cache_file() calls get_nvidia_gpu_pci_bus() which parses lspci output; if a stale udev removal rule was hiding the NVIDIA device the function called sys.exit(1), aborting before cleanup() ever ran. Fix: skip cache creation when the target switch is 'hybrid', since hybrid mode never consumes the cached PCI bus value.
1 parent 87f94af commit d5df344

1 file changed

Lines changed: 8 additions & 2 deletions

File tree

envycontrol.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,11 @@ def adapter(self):
647647
global get_nvidia_gpu_pci_bus
648648
use_cache = os.path.exists(CACHE_FILE_PATH)
649649

650-
if self.is_hybrid(): # recreate cache file when in hybrid mode
650+
# Only cache the GPU PCI bus when leaving hybrid mode.
651+
# Switching *to* hybrid never needs the cached value and the GPU
652+
# may not be visible via lspci if old udev removal rules are still
653+
# in place, which would make create_cache_file() exit early.
654+
if self.is_hybrid() and self.app_args.switch != 'hybrid':
651655
self.create_cache_file()
652656

653657
if use_cache:
@@ -717,7 +721,9 @@ def write_cache_file(self):
717721

718722
def get_current_mode():
719723
mode = 'hybrid'
720-
if os.path.exists(BLACKLIST_PATH) and (os.path.exists(UDEV_INTEGRATED_PATH) or os.path.exists('/lib/udev/rules.d/50-remove-nvidia.rules')):
724+
if (os.path.exists(BLACKLIST_PATH) or
725+
os.path.exists(UDEV_INTEGRATED_PATH) or
726+
os.path.exists('/lib/udev/rules.d/50-remove-nvidia.rules')):
721727
mode = 'integrated'
722728
elif os.path.exists(XORG_PATH) and os.path.exists(MODESET_PATH):
723729
mode = 'nvidia'

0 commit comments

Comments
 (0)