什么是循环登录
开机/重启后的登录界面,分辨率变得很低,并且输入密码后,黑屏一闪而过又重新回到输入密码的界面,如此循环无法跳出,俗称“循环登录”。
为什么会循环登录
造成循环登录有多种可能的原因:
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. 系统升级导致
如果重启后发现显卡驱动挂了,而通过查找 /var/log/apt/history.log.1
发现关机前最后一次的apt记录,里面执行过sudo apt upgrade
,那么可以仔细看一下升级了什么。我这里在2020-10-30升级,内核升级到了4.4.0-193,附带的,gcc/g++从5.4.0被升级到了5.5.0。
这有什么问题呢?可能是gcc版本升级,导致和原来的DKMS中的显卡驱动的内核模块冲突。毕竟,原来是用gcc5.4生成的ko。而重装显卡驱动450时选dkms后也会报错说编译器版本不匹配。于是这次放弃选择DKMS了。
6. 其他
诸如检查~/.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
关掉才能代表深度学习的正义:
我的机器上是/etc/apt/apt.conf.d/20auto-upgrades
,有些机器上可能是/etc/apt/apt.conf.d/10periodic
。编辑此文件,找到并修改它的取值为"0":
sudo vim /etc/apt/apt.conf.d/20auto-upgrades
找到并修改它的取值为"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
sudo vim /etc/apt/apt.conf.d/20auto-upgrades
找到并修改它的取值为"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 search 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显卡的ubuntu笔记本,暂时不能实验,大概猜测一下可行的方法:
确保显卡驱动是适合笔记本(notebook)的,以和台式机区别。同一型号显卡,笔记本上和台式机上也许并不完全一样,驱动可能有差别。
如果仍然失败,考虑到笔记本通常默认用集显作为显示输出,台式机默认用独显做显示输出;则先卸载掉刚才安装的驱动,再重新加入
–no-opengl-files
选项安装。而后续要用到opengl的情况(譬如基于vulkan的优化加速库),则在安装cuda时,注意勾选opengl、取消勾选显卡驱动(不确定,只是一时的想法,求验证)
参考
NVIDIA CUDA Installation Guide for Linux,全面,但不全都正确可用
解决Driver/library version mismatch,中文博客中比较深入的一篇
Command to rebuild all DKMS modules for all installed kernels?,启发了我找到dkms的正确配置方式
ubuntu 禁止/取消系统自动更新的方法
http://www.jeepxie.net/article/581478.html
解决Nvidia显卡的电脑安装Ubuntu及驱动的各种坑