Пример #1
0
def _check_bbswitch_module(config):

    if config["optimus"]["switching"] == "bbswitch" and not checks.is_module_available("bbswitch"):
        print("WARNING : bbswitch is enabled in the configuration file but the bbswitch module does"
              " not seem to be available for the current kernel. Power switching will not work.\n"
              "You can install bbswitch for the default kernel with \"sudo pacman -S bbswitch\" or"
              " for all kernels with \"sudo pacman -S bbswitch-dkms\".\n")
Пример #2
0
def _load_acpi_call():

    if not checks.is_module_available("acpi_call"):
        raise KernelSetupError("Module acpi_call not available for current kernel.")

    print("Loading acpi_call module")
    try:
        exec_bash("modprobe acpi_call")
    except BashError as e:
        raise KernelSetupError("Cannot load acpi_call : %s" % str(e))
Пример #3
0
def _load_bbswitch():

    if not checks.is_module_available("bbswitch"):
        raise KernelSetupError("Module bbswitch not available for current kernel.")

    print("Loading bbswitch module")
    try:
        exec_bash("modprobe bbswitch")
    except BashError as e:
        raise KernelSetupError("Cannot load bbswitch : %s" % str(e))
Пример #4
0
def _check_nvidia_module(switch_mode):

    if switch_mode == "nvidia" and not checks.is_module_available("nvidia"):
        print("WARNING : the nvidia module does not seem to be available for the current kernel."
              " It is likely the Nvidia driver was not properly installed. GPU switching will probably fail,\n"
              " continue anyway ? (y/N)")

        confirmation = _ask_confirmation()

        if not confirmation:
            sys.exit(0)
Пример #5
0
def _set_base_state(config):

    _unload_nvidia_modules()
    _unload_nouveau()

    switching_mode = config["optimus"]["switching"]

    try:
        if switching_mode == "bbswitch":
            _load_bbswitch()
        elif switching_mode == "acpi_call":
            _load_acpi_call()
    except KernelSetupError as e:
        print(
            "ERROR : error loading modules for %s. Continuing anyways. Error is : %s"
            % (switching_mode, str(e)))
        if not checks.is_module_available(switching_mode):
            print(
                "%s is not available for the current kernel. Is the corresponding package installed ?"
            )

    if checks.is_module_loaded("bbswitch"):
        _try_set_bbswitch_state("ON")

    if checks.is_module_loaded("acpi_call"):

        try:
            last_acpi_call_state = var.read_last_acpi_call_state()
            should_send_acpi_call = (last_acpi_call_state == "OFF")
        except var.VarError:
            should_send_acpi_call = False

        if should_send_acpi_call:
            _try_set_acpi_call_state("ON")

    if not pci.is_nvidia_visible():

        print("Nvidia card not visible in PCI bus, rescanning")
        _try_rescan_pci()

    _try_pci_reset(config)

    if switching_mode == "bbswitch":
        _load_bbswitch()
    else:
        _unload_bbswitch()

    if switching_mode == "none":
        _try_custom_set_power_state("ON")

    _try_set_pci_power_state("on")
Пример #6
0
def _get_available_modules():
    MODULES = [
        "nouveau", "bbswitch", "acpi_call", "nvidia", "nvidia_drm",
        "nvidia_modeset"
    ]
    return [module for module in MODULES if checks.is_module_available(module)]
Пример #7
0
def switch_to_nvidia(config):

    print("Switching to Nvidia")

    if config["optimus"]["switching"] == "bbswitch":

        if not checks.is_module_available("bbswitch"):
            print(
                "Module bbswitch not available for current kernel. Skipping bbswitch power switching."
            )

        else:
            # bbswitch module
            print("Loading bbswitch module")
            try:
                exec_bash("modprobe bbswitch")
            except BashError as e:
                raise SwitchError("Cannot load bbswitch : %s" % str(e))

            # bbswitch switching
            print("Ordering ON via bbswitch")
            exec_bash("echo ON | tee /proc/acpi/bbswitch")
            if not checks.is_gpu_powered():
                raise SwitchError("bbswitch refuses to turn ON the GPU")
            else:
                print("bbswitch reports that the GPU is ON")

    # Unloading nouveau
    print("Unloading nouveau module")
    try:
        exec_bash("modprobe -r nouveau")
    except BashError as e:
        raise SwitchError("Cannot unload nouveau : %s" % str(e))

    # Nvidia modules
    print("Loading Nvidia modules")

    pat_value = {"yes": 1, "no": 0}[config["nvidia"]["PAT"]]

    if not checks.is_pat_available():
        print(
            "Warning : Page Attribute Tables are not available on your system.\n"
            "Disabling the PAT option for Nvidia.")
        pat_value = 0

    try:
        exec_bash("modprobe nvidia NVreg_UsePageAttributeTable=%d" % pat_value)
        if config["nvidia"]["modeset"] == "yes":
            exec_bash("modprobe nvidia_drm modeset=1")
        else:
            exec_bash("modprobe nvidia_drm modeset=0")

    except BashError as e:
        raise SwitchError("Cannot load Nvidia modules : %s" % str(e))

    # PCI power management
    if config["optimus"]["pci_power_control"] == "yes":
        if config["optimus"]["switching"] == "bbswitch":
            print("bbswitch is enabled, pci_power_control option ignored.")
        else:
            try:
                pci.set_power_management(False)
            except pci.PCIError as e:
                print("WARNING : Cannot set PCI power management : %s" %
                      str(e))

    # Xorg configuration
    print("Configuring Xorg...")
    configure_xorg(config, mode="nvidia")

    # Login managers configuration
    print("Configuring login managers..")
    configure_login_managers(config, mode="nvidia")
Пример #8
0
def switch_to_intel(config):

    print("Switching to Intel")

    # Nvidia modules
    print("Unloading Nvidia modules")

    try:
        exec_bash("modprobe -r nvidia_drm nvidia_modeset nvidia_uvm nvidia")
    except BashError as e:
        raise SwitchError("Cannot unload Nvidia modules : %s" % str(e))

    if config["optimus"]["switching"] == "bbswitch":

        if not checks.is_module_available("bbswitch"):
            print(
                "Module bbswitch not available for current kernel. Skipping bbswitch power switching."
            )

        else:
            # Load bbswitch
            print("Loading bbswitch module")
            try:
                exec_bash("modprobe bbswitch")
            except BashError as e:
                raise SwitchError("Cannot load bbswitch : %s" % str(e))

            # bbswitch switching
            print("Ordering OFF via bbswitch")
            exec_bash("echo OFF | tee /proc/acpi/bbswitch")
            if checks.is_gpu_powered():
                raise SwitchError("bbswitch refuses to turn OFF the GPU")
            else:
                print("bbswitch reports that the GPU is OFF")

    elif config["optimus"]["switching"] == "nouveau":

        modeset_value = {"yes": 1, "no": 0}[config["intel"]["modeset"]]

        # Loading nouveau
        print("Loading nouveau module")
        try:
            exec_bash("modprobe nouveau modeset=%d" % modeset_value)
        except BashError as e:
            raise SwitchError("Cannot load nouveau : %s" % str(e))

    else:
        print("Power switching backend is disabled.")

    # PCI power management
    if config["optimus"]["pci_power_control"] == "yes":
        if config["optimus"]["switching"] == "bbswitch":
            print("bbswitch is enabled, pci_power_control option ignored.")
        else:
            try:
                pci.set_power_management(True)
            except pci.PCIError as e:
                print("WARNING : Cannot set PCI power management : %s" %
                      str(e))

    # Xorg configuration
    print("Configuring Xorg...")
    configure_xorg(config, mode="intel")

    # Login managers configuration
    print("Configuring login managers..")
    configure_login_managers(config, mode="intel")
def main():

    # Arguments parsing
    parser = argparse.ArgumentParser(
        description="Client program for the Optimus Manager tool.\n"
        "https://github.com/Askannz/optimus-manager")
    parser.add_argument('-v',
                        '--version',
                        action='store_true',
                        help='Print version and exit.')
    parser.add_argument('--print-mode',
                        action='store_true',
                        help="Print the current mode.")
    parser.add_argument(
        '--switch',
        metavar='MODE',
        action='store',
        help="Set the GPU mode to MODE and restart the display manager. "
        "Possible modes : intel, nvidia, auto (checks the current mode and switch to the other). "
        "WARNING : All your applications will close ! Be sure to save your work."
    )
    parser.add_argument(
        '--set-startup',
        metavar='STARTUP_MODE',
        action='store',
        help="Set the startup mode to STARTUP_MODE. Possible modes : "
        "intel, nvidia, nvidia_once (starts with Nvidia and reverts to Intel for the next boot)"
    )
    parser.add_argument('--print-startup',
                        action='store_true',
                        help="Print the current startup mode.")
    parser.add_argument(
        '--no-confirm',
        action='store_true',
        help="Do not ask for confirmation before switching GPUs.")
    parser.add_argument(
        '--cleanup',
        action='store_true',
        help=
        "Remove auto-generated configuration files left over by the daemon.")
    args = parser.parse_args()

    # Config loading
    if not args.version:
        try:
            config = load_config()
        except ConfigError as e:
            print("Error loading config file : %s" % str(e))
            sys.exit(1)

    #
    # Arguments switch

    if args.version:
        print("Optimus Manager (Client) version %s" % envs.VERSION)
        sys.exit(0)

    elif args.print_mode:

        try:
            mode = checks.read_gpu_mode()
        except checks.CheckError as e:
            print("Error reading mode : %s" % str(e))
            sys.exit(1)

        print("Current mode : %s" % mode)

    elif args.print_startup:

        try:
            startup_mode = var.read_startup_mode()
        except var.VarError as e:
            print("Error reading startup mode : %s" % str(e))
            sys.exit(1)

        print("Current startup mode : %s" % startup_mode)

    elif args.switch:

        if args.switch not in ["auto", "intel", "nvidia"]:
            print("Invalid mode : %s" % args.switch)
            sys.exit(1)

        if not checks.is_daemon_active():
            print(
                "The optimus-manager service is not running. Please enable and start it with :\n\n"
                "sudo systemctl enable optimus-manager\n"
                "sudo systemctl start optimus-manager\n")
            sys.exit(1)

        if args.switch == "auto":
            try:
                gpu_mode = checks.read_gpu_mode()
            except checks.CheckError as e:
                print("Error reading mode: %s" % str(e))
                sys.exit(1)

            if gpu_mode == "nvidia":
                switch_mode = "intel"
            else:
                switch_mode = "nvidia"
            print("Switching to : %s" % switch_mode)

        else:
            switch_mode = args.switch

        # Printing warnings if something is wrong
        if config["optimus"][
                "switching"] == "bbswitch" and not checks.is_module_available(
                    "bbswitch"):
            print(
                "WARNING : bbswitch is enabled in the configuration file but the bbswitch module does"
                " not seem to be available for the current kernel. Power switching will not work.\n"
                "You can install bbswitch for the default kernel with \"sudo pacman -S bbswitch\" or"
                " for all kernels with \"sudo pacman -S bbswitch-dkms\".\n")

        if switch_mode == "nvidia" and not checks.is_module_available(
                "nvidia"):
            print(
                "WARNING : the nvidia module does not seem to be available for the current kernel."
                " It is likely the Nvidia driver was not properly installed. GPU switching will probably fail,"
                " continue anyway ? (y/N)")
            ans = input("> ").lower()

            if ans == "y":
                pass
            elif ans == "n" or ans == "N":
                print("Aborting.")
                sys.exit(0)
            else:
                print("Invalid choice. Aborting")
                sys.exit(0)

        if args.no_confirm:
            send_command(switch_mode)
        else:
            print(
                "You are about to switch GPUs. This will restart the display manager and all your applications WILL CLOSE.\n"
                "(you can pass the --no-confirm option to disable this warning)\n"
                "Continue ? (y/N)")
            ans = input("> ").lower()

            if ans == "y":
                send_command(switch_mode)
            elif ans == "n" or ans == "N":
                print("Aborting.")
                sys.exit(0)
            else:
                print("Invalid choice. Aborting")
                sys.exit(0)

    elif args.set_startup:

        if args.set_startup not in ["intel", "nvidia", "nvidia_once"]:
            print("Invalid startup mode : %s" % args.set_startup)
            sys.exit(1)

        send_command("startup_" + args.set_startup)

    elif args.cleanup:

        if os.geteuid() != 0:
            print("You need to execute the command as root for this action.")
            sys.exit(1)

        clean_autogenerated()
        var.remove_startup_mode_var()
        var.remove_requested_mode_var()

    else:

        print("Invalid arguments.")
Пример #10
0
def _setup_intel_mode(config):

    # Resetting the Nvidia card to its base state
    _set_base_state(config)

    # Handling power switching according to the switching backend
    if config["optimus"]["switching"] == "nouveau":

        try:
            _load_nouveau(config)
        except KernelSetupError as e:
            print("ERROR : cannot load nouveau. Moving on. Error is : %s" %
                  str(e))

    elif config["optimus"]["switching"] == "bbswitch":

        if not checks.is_module_available("bbswitch"):
            print(
                "ERROR : module bbswitch is not available for the current kernel."
                " Is bbswitch or bbswitch-dkms installed ? Moving on...")

        else:
            try:
                _load_bbswitch()
            except KernelSetupError as e:
                print(
                    "ERROR : cannot load bbswitch. Moving on. Error is : %s" %
                    str(e))
            else:
                if config["optimus"]["pci_remove"] == "yes":
                    pci.remove_nvidia()
                _set_bbswitch_state("OFF")

    elif config["optimus"]["switching"] == "acpi_call":

        if not checks.is_module_available("acpi_call"):
            print(
                "ERROR : module acpi_call is not available for the current kernel."
                " Is acpi_call or acpi_call-dkms installed ? Moving on...")

        else:
            try:
                _load_acpi_call()
            except KernelSetupError as e:
                print(
                    "ERROR : cannot load acpi_call. Moving on. Error is : %s" %
                    str(e))
            else:
                if config["optimus"]["pci_remove"] == "yes":
                    pci.remove_nvidia()
                _set_acpi_call_state("OFF")

    elif config["optimus"]["switching"] == "none":
        pass

    # Handling PCI power control
    if config["optimus"]["pci_power_control"] == "yes":
        if config["optimus"]["switching"] == "bbswitch":
            print("bbswitch is enabled, pci_power_control option ignored.")
        elif config["optimus"]["switching"] == "acpi_call":
            print("acpi_call is enabled, pci_power_control option ignored.")
        else:
            pci.set_power_state("auto")