彻底解决ubuntu显卡驱动和循环登录问题

目录彻底解决ubuntu显卡驱动和循环登录问题什么是循环登录为什么会循环登录1. 显卡驱动相关原因,导致循环登录2. 改配置文件时系统环境变量被改坏,导致循环登录3. 磁盘空间不足,导致循环登录4. 输入法冲突导致5. 其他正确的配置显卡驱动显卡驱动和内核的关系unattended-upgrade是什么?能关闭吗?CUDA和显卡驱动的关系正确安装显卡的姿势参考

什么是循环登录

开机/重启后的登录界面,分辨率变得很低,并且输入密码后黑屏一闪而过又重新回到输入密码的界面,如此循环无法跳出,俗称“循环登录”。

为什么会循环登录

造成循环登录有多种可能的原因:

1. 显卡驱动相关原因,导致循环登录

最常见的是,内核版本和显卡驱动版本不兼容导致循环登录。 例如内核升级但没有配置支持显卡驱动。这是本文重点关注的一类原因。

也有比较少见的,独显和集显共存问题,nvidia-prime切换后可以使用:

ubuntu循环登录巧妙处理

2. 改配置文件时系统环境变量被改坏,导致循环登录

例如/etc/profile/etc/environment~/.profile~/.bashrc, ~/.bash_profile等文件中配置PATH,原本希望append一个路径,但却设置成了PATH只等于这一个路径。通常是Linux菜鸟或粗心导致。

解决ubuntu16.04循环登录问题 这篇尝试添加PyCharm的bin路径到PATH,但忘记追加原有PATH的值。实际上完全没必要添加PyCharm,Dash里搜索即可。

启动Ubuntu时,密码正确但是出现循环登陆的现象 这篇尝试添加JDK的bin目录到PATH,目测是把PATH的值改成只剩JDK的bin目录导致进不去桌面。

Ubuntu陷入登录循环 这篇总结贴中提到.profile文件被修改的时候写了“错别字”

3. 磁盘空间不足,导致循环登录

例如/var/log或/home满了。df -h可查看磁盘使用情况。

ubuntu14.04开机登录死循环 该博主删除大量无效log文件后问题得以解决。

Ubuntu陷入登录循环 提到HOME分区满导致。

4. 输入法冲突导致

例如多个输入法共存时可能触发。

Ubuntu 登录循环问题 这篇提到fcitx和搜狗输入法的设定不正确导致的。

5. 其他

诸如检查~/.Xauthority~/.gconf等配置文件,检查和修改权限,或者干脆删除。

再例如检查~/.xsession-errors文件,检查/var/log/Xorg.0.log文件。

这类方法基本上不管用,偶尔管用也并不能让人知道先前为什么循环登录,有瞎搞的嫌疑。

还有提到“用adduser命令新建一个用户,看能不能登录进去”:
ubuntu登陆无限循环

此方法确实能够验证先前用户home目录下配置文件有问题,不过迁移用户数据也是比较不可取的。

正确的配置显卡驱动

显卡驱动和内核的关系

原理上,显卡是硬件,需要显卡驱动的正确配置,才能够被操作系统所管理使用;操作系统识别显卡驱动后,对用户态提供显卡的使用接口。

具体到Ubuntu系统,它用的是linux内核。有意或无意的更新linux内核后,重启的机器会默认加载新版内核,而如果内核与显卡驱动不兼容,就导致了循环登录

最常见的解决思路:卸载并重新安装显卡驱动。新装的驱动可以和原来版本相同,也可以是新版。然而这种做法并没有从根本上解决问题:为什么我的内核会更新?我好象并没有更新过内核?

一个合格的Linux用户,应当会查看系统日志、定位报错,并解决问题。查看了/var/log/apt/history.log,我发现了关键:

Start-Date: 2020-05-03  16:51:58
Commandline: /usr/bin/unattended-upgrade                                                                                    
Install: linux-modules-extra-4.15.0-99-generic:amd64 (4.15.0-99.100~16.04.1, automatic), linux-headers-4.15.0-99:amd64 (4.  15.0-99.100~16.04.1, automatic), linux-modules-4.15.0-99-generic:amd64 (4.15.0-99.100~16.04.1, automatic), linux-headers-4. 15.0-99-generic:amd64 (4.15.0-99.100~16.04.1, automatic), linux-image-4.15.0-99-generic:amd64 (4.15.0-99.100~16.04.1,       automatic)

没错,unattended-upgrade,这家伙意思是自动升级,在5月3日 16:51:58悄悄的安装了新版内核(4.15.0-99)

有没有办法关掉unattended-upgrade呢?有,后文介绍。

如果保持unattended-upgrade打开,能不能让显卡驱动自动适配新内核?能,而且是推荐的方式(DKMS),不过也需要一番设置。

unattended-upgrade是什么?能关闭吗?

通过man命令可以知道,unattended-upgrade在每天的cron任务(/etc/cron.daily/apt-compat)中被在随机的时间点触发使用,更新了内核。

对服务器而言,unattended-upgrade安装了新版内核,安全角度来看是一件好事因为修复了漏洞;但对于使用ubuntu做深度学习训练的人来说,这显得多此一举,帮了倒忙。即使不使用图形界面而只是用ssh远程连接使用,也会遭遇如下类似报错:

NVIDIA-SMI has failed because it couldn’t communicate with the NVIDIA driver. Make sure that the latest NVIDIA driver is installed and running.

而此条报错也很直白的表明了,内核版本和显卡驱动版本不兼容,显卡罢工了,深度学习训练暂停了。

关闭unattended-upgrade

对付暴力的唯一办法就是更加暴力。把unattended-upgrade关掉才能代表深度学习的正义:

关闭unattended-upgrade
/etc/apt/apt.conf.d目录下,查找包含Unattended-Upgrade的文件:

cd /etc/apt/apt.conf.d
ag 'Unattended-Upgrade'

我的机器上是/etc/apt/apt.conf.d/20auto-upgrades,有些机器上可能是/etc/apt/apt.conf.d/10periodic。编辑此文件,找到并修改它的取值为"0":

APT::Periodic::Unattended-Upgrade "0";

不过,关闭unattended-upgrade也只是杜绝了以后莫名其妙的被更新内核,当前已经被更新了内核而驱动版本不匹配,还是要搞一下显卡驱动。

CUDA和显卡驱动的关系

搞深度学习要用CUDA来加速训练,有时候也用来部署加速。

CUDA安装包里面带有兼容版本的显卡驱动。没错,必须搭配合适版本的显卡驱动,才能支持CUDA,否则装好的CUDA也永不上。

举例:*华公司的AI集群训练系统,物理机的显卡驱动迟迟不肯更新,导致训模师在2020年还只能用CUDA8这样落后的东西。*华的sa们都在忙什么?

说回CUDA安装包里的显卡驱动,个人不建议安装它。尽管它确实在多数情况下能让CUDA正常运行起来,但是这一版本的显卡驱动在安装的时候不会注册dkms模块,这就导致一旦更新了linux内核,重启机器后显卡驱动再次和内核不兼容,图形界面桌面进不去,CUDA用不了,深度学习训练推理都罢工。

而手动从nvidia官网下载的显卡驱动(standalone版本),是带有dkms注册支持功能的。在此倡议:Ubuntu系统下,请不要安装CUDA安装包里的显卡驱动,请到nvidia官网手动下载.run格式的显卡驱动,手动下载安装

有人会问:ppa:graphics-drivers/ppa这个仓库不香吗?用apt安装CUDA和显卡驱动不是更方便吗?

我觉得这类用户没有考虑过多个版本的CUDA共存的问题,他们也不曾遇到当急需用最近版CUDA而ppa源里的显卡驱动版本过低时的那种无奈。

正确安装显卡的姿势

关闭unattended-upgrade
/etc/apt/apt.conf.d目录下,查找包含Unattended-Upgrade的文件:

cd /etc/apt/apt.conf.d
ag 'Unattended-Upgrade'

我的机器上是/etc/apt/apt.conf.d/20auto-upgrades,有些机器上可能是/etc/apt/apt.conf.d/10periodic。编辑此文件,找到并修改它的取值为"0":

APT::Periodic::Unattended-Upgrade "0";

获取内核相关包

sudo apt install linux-headers-$(uname -r)
sudo apt install linux-headers-generic

禁用开源驱动nouveau

新建/etc/modprobe.d/blacklist-nouveau.conf,内容:

blacklist nouveau
options nouveau modeset=0
sudo update-initramfs -u

正确的卸载显卡驱动

想要正确的安装显卡驱动,必须知道怎么正确的卸载显卡驱动。有时候使用的机器是别人之前维护的,而前任维护者也许配置的并不合理,需要先检查再按自己的风格配置:

.run文件安装的显卡驱动,卸载:sudo /usr/bin/nvidia-uninstall,或找到原始的.run文件,执行sudo bash ./xxx.run --uninstall

cuda安装包里的显卡驱动,卸载:sudo /usr/bin/nvidia-uninstall

apt repo下载安装的:

sudo aptitude search nvidia | grep '^i' #查看
sudo apt remove --purge nvidia-XXX #例如我是nvidia-384

正确的安装dkms依赖包

尽管standalone版本的nvidia显卡驱动已经内置了注册dkms的功能,但ubuntu16.04并不默认支持dkms。也就是说,虽然你满心欢喜的在安装显卡驱动时选择了dkms,但是某天因为unattended-upgrade更新了内核,显卡会再次罢工。

正确姿势:

sudo apt install dkms

查找和nvidia相关的dkms包:

aptitude show dkms | ag 'nvidia'
sudo apt install bbswitch-dkms

安装后,得到/usr/lib/dkms_autoinstaller这一可执行文件。

正确的获取显卡驱动

前面提到过,不要用CUDA安装包里的显卡驱动,它不带dkms支持会导致以后问题频发。请到官网自行下载适合版本的显卡驱动。

sudo init 3

sudo bash ./NVIDIA-Linux-x86_64-440.82.run

注意选择dkms支持,选择32位兼容。

正确的配置dkms

ls /var/lib/initramfs-tools | sudo xargs -n1 /usr/lib/dkms/dkms_autoinstaller start

这会把所有内核模块打入到所有内核中。然后重启系统即可。

如果不重启,无线网卡和CUDA可能无法使用。

参考

NVIDIA CUDA Installation Guide for Linux,全面,但不全都正确可用

解决Driver/library version mismatch,中文博客中比较深入的一篇

Command to rebuild all DKMS modules for all installed kernels?,启发了我找到dkms的正确配置方式

ubuntu 禁止/取消系统自动更新的方法