Когда происходит сбой в системе и она перестает загружаться, многие пользователи не знают, что делать. Конечно, лучше вообще не допускать таких ситуаций, но, если уж подобное случилось, нужно воспринять это как данность и разобраться в проблеме.
Введение
Для начала стоит рассмотреть, какие вообще бывают нештатные ситуации, после которых система не грузится. Условно их можно разделить на четыре вида:
- Сбой файловой системы
- Некорректное обновление дистрибутива. Конечно, именитые компании, такие как Canonical или Red Hat, очень стараются не допускать подобных ситуаций, но ведь и на старуху бывает проруха.
- Некорректно сконфигурированная графическая подсистема и/или кривые драйверы, чаще всего проприетарные.
- Невнимательность пользователя. О, чего тут только нет! Перечислю основные возможности сломать систему:
- забыть пароль root (как вариант — свой собственный) или загрузчика;
- перезаписать таблицу разделов;
- удалить какой-нибудь крайне важный файл;
- установить программу из неизвестного источника. Справедливости ради надо сказать, что если пользователь компилирует из-под своей учетной записи и ставит программы исключительно в свой домашний каталог (что, впрочем, бывает крайне редко), то максимум, что сможет сделать эта программа, — занять все ресурсы и/или запороть конфиги в домашнем каталоге (необходимо отметить, что это верно именно для криво написанных программ, не для зловредов).
Это, пожалуй, самые распространенные варианты сбоя, после которого может понадобиться реанимировать систему. Рассмотрим теперь, как это делать.
Забытые пароли
Для Linux способы сброса паролей пользователей разнятся от дистрибутива к дистрибутиву. Далее я опишу самый универсальный метод.
В загрузочном меню GRUB выдели дистрибутив и нажми клавишу . Затем выбери строку, начинающуюся с kernel, и снова нажми (в случае с GRUB2 — linux и повторно нажимать не надо). В конце строки допиши init=/bin/sh
. Эта команда запускает вместо init/systemd
процесс оболочки, в котором ты можешь изменить пароль. Но перед этим тебе необходимо перемонтировать ФС в режиме чтения/записи, для чего выполни следующую команду:
# /sbin/mount -no remount,rw /
Уже после этого ты можешь выполнить команду passwd
или ее же, но с именем пользователя в качестве аргумента. После этого нужно перезагрузиться — но команды shutdown
/reboot
в этом режиме не всегда работают. Выход есть: используй клавишу , Люк! А именно — зажимая клавиши и , с интервалом в 3–4 секунды нажми следующие буквы: R E I S S U B. Итогом будет перезагрузка, и после нее ты сможешь заходить под новым паролем.
В FreeBSD ситуация сложнее. Обычно советуют грузиться в однопользовательском режиме и оттуда уже менять пароль. Однако если в файле /etc/ttys
консоль отмечена как insecure, то этот метод, очевидно, не подходит, и тут не обойтись без LiveCD (в параметрах ядра, которые могут быть установлены в загрузчике, есть переменная kern.init_path, но сброс, а затем присвоение этой переменной пути к какой-либо оболочке ни на что не влияет). Рассмотрим, как именно сбросить пароль с его помощью.
- Качаем (и записываем) Frenzy и грузимся с него.
- Подключаем разделы FreeBSD в режиме чтение/запись.
- Делаем
chroot
на подмонтированную ФС. - Делаем резервные копии файлов
passwd
,master.passwd
,pwd.db
иspwd.db
. - Задаем команду
passwd
и ставим пароль. - Выходим из chroot, задаем команду
sync
, отмонтируем и перезагружаемся.
В случае с потерей пароля на GRUB/GRUB2 тебе необходимо загрузиться с LiveCD и поставить другой пароль. Для GRUB2 это делается путем редактирования файла/boot/grub/grub.cfg
(после перезагрузки не забудь поставить новый зашифрованный пароль в соответствующий файл в /etc/grub.d/
):
# <...>
set superusers="root"
# Забытый пароль
#password_pbkdf2 root grub.pbkdf2.sha512.10000.FD7709726BA498BA0A116E09217D1B3D9D677605546EA2BFAD134581877694B3A8DC7AE0AAC1EBA51A2B8C153EF970617DB126D2B0860A9B0C0F9EA6769385C8.E43348DB1945B9428704A43685B9B41DCB0027098BFC33AE67FADFB1E78F5AABD757FAB9CD5D3A448100AF7B20E45DF958102A84B6CDE42D0225088567DEAC32
# Новый пароль (для упрощения изменения его мы не хешируем)
password root newpass
# <...>
Для старого GRUB достаточно заменить в файле /boot/grub/menu.lst
строку password --md5 password_hash на password newpass.
Хакер #179. Интернет вещей — новый вектор атак
Испорченный загрузчик
В случае порчи загрузчика сперва нужно определить, какой из них используется в твоей системе. Как правило, в Ubuntu, начиная с версии 9.10, используется вторая версия GRUB. Однако проверить это нетрудно. Прежде всего загрузись с LiveCD и пробрось chroot. О том, как это сделать, написано в одном из следующих разделов. Помни, что в случае, если /boot
находится на отдельном разделе, его также необходимо подмонтировать. Наиболее ярким индикатором, что установлен GRUB2, служит присутствие каталога /etc/grub.d/
. Для полной же уверенности проверь также наличие файла grub-mkpasswd-pbkdf2
и отсутствиеgrub-crypt
с помощью команды whereis
.
В случае если в качестве загрузчика используется вторая версия GRUB и ты точно уверен, что он установлен, к примеру на /dev/sda
, набирай следующую команду:
# grub-install /dev/sda
Если возникли ошибки, могут помочь опции проверки device map '--recheck' и отключения проверки наличия флоппи-дисковода '--no-floppy'.
Для установки GRUB Legacy используй ту же самую команду. Замечу, что опция '--recheck' в версии программы для grub-legacy
недоступна.
Кривое обновление
Эта ситуация неприятна еще и тем, что иногда ее видно не сразу. В идеале конфигурационные файлы в пределах одной версии дистрибутива не должны меняться. Реальный мир, тем не менее, вносит свои корректировки — даже несмотря на то, что разработчики LTS-версий дистрибутива стараются делать бэкпортирование как можно более безболезненным, это не всегда получается. Наиболее правильный способ решить эту проблему — почитать логи и поправить конфиги. Но если этой возможности нет, остается только даунгрейд.
В системах, основанных на RHEL, даунгрейд можно осуществить сразу несколькими путями. Самый древний метод — использовать опцию '--rollback' RPM. Например, для отката изменений на неделю назад необходимо выполнить следующую команду:
# rpm -Uvh --rollback '1 week ago'
Этот метод, однако, по современным меркам весьма неудобен, особенно если учитывать, что сейчас все пользуются yum
. Для даунгрейда пакета с помощью yum
можно использовать команду yum downgrade
. Например, так:
# yum downgrade samba-common
Замечу, что зависимости не даунгрейдятся, и их нужно указывать вместе с пакетом, который подвергается этой операции.
В системах новее RHEL6 есть еще один метод, основанный на истории действий yum
. Для его применения нужно прежде всего задать следующую команду:
# yum history
Затем посмотреть номер действия, убедиться, что это именно то действие, и откатиться:
# yum history info 38
# yum history undo 38
Для Ubuntu (и других систем, использующих apt-get
) нужно сначала удалить пакет, а затем установить нужную версию (перед этим обязательно сохраняй конфиги!):
# apt-get remove php
# apt-get install php=5.3.2
Нужно учесть, что для ядер это не подходит — новые ядра именно устанавливаются, а не обновляются.
В случае с портами FreeBSD существует утилита portdowngrade
, которая, впрочем, сейчас служит в качестве фронтенда к subversion
, то есть для ее использования необходимо, чтобыsvn
был установлен. Использовать ее очень просто — сперва мы ищем ту ревизию, к которой нужно откатиться, затем откатываемся и ставим этот порт:
# /usr/local/sbin/portdowngrade emulators/dosbox
# /usr/local/sbin/portdowngrade emulators/dosbox 251605
# cd /usr/ports/emulators/dosbox
# make deinstall install clean
Удаление файла
Восстановление удаленных файлов сильно зависит от файловой системы, и гарантии, что ты их восстановишь, нет никакой. Вначале опишу восстановление данных с ext2/3/4 под Ubuntu. Первым делом, если ты обнаружил, что какой-то файл удален, сразу насильно выключай компьютер - и чем раньше ты обнаружишь это, тем лучше. Затем грузись с LiveCD и установи программу extundelete
:
$ sudo apt-get install extundelete
Если у тебя есть раздел, куда восстанавливать, подмонтируй его, перейди в соответствующий каталог и набери следующую команду:
$ sudo extundelete --restore-all /dev/sda3
Если же у тебя нет раздела, в который можно помещать восстанавливаемые файлы… тогда вместо --restore-all напиши --restore-file. Например, так:
$ sudo extundelete --restore-file /etc/shadow /dev/sda3
Отмечу, что путь к файлу задается относительно его корня — то есть если у тебя отдельный раздел /boot
и ты случайно удалил файл /boot/grub/grub.cfg
, то в качестве восстанавливаемого файла будет фигурировать /grub/grub.cfg
.
В случае с Btrfs в версиях выше, чем 0.20, имеется команда btrfs restore
. К сожалению, по умолчанию она не может восстанавливать конкретные файлы – для этого необходима сборкаbtrfs-progs
от josefbacik. Пример использования:
$ sudo btrfs restore /dev/sda9 /mnt/restore
Что до FreeBSD, то ситуация с ней сложнее. Для восстановления удаленных данных в стандартной поставке ничего нет, поэтому берем какой-нибудь LiveCD — да тот же Ubuntu — и ставим пакет testdisk
, в составе которого имеется photorec
. К сожалению, эта программа (пока?) не понимает формата разделов и слайсов FreeBSD и его файловую систему. Тем не менее это не мешает им пользоваться. Запустим ее для раздела sda3:
$ sudo photorec /dev/sda3
В появившемся меню нажмем — поскольку мы уже выбрали раздел — и затем выберем Options". Там включаем опции по вкусу, выйдем из меню и вперед — жмем Search. Перед поиском photorec
попросит указать каталог, куда сохранять. Разумеется, процесс это небыстрый, поэтому запасись терпением.
INFO
В пакет testdisk, помимо photorec, входит собственно сам testdisk — утилита, позволяющая восстанавливать случайно удаленные разделы из таблицы разделов.
Помимо этих методов, есть еще один метод, почти универсальный для *nix-систем. Этот метод не требует немедленного отключения питания. Но не спеши радоваться, он доступен только в том случае, если ты удалил файл, открытый в другом приложении. Для восстановления файла тебе нужно узнать PID приложения, перейти в каталог
/proc/<PID>/fd
, найти ссылку на удаленный файл и с помощью cat
его восстановить.
INFO
В случае работы с поврежденными ФС необходимо быть чрезвычайно осторожным. Трижды убедись, что ты понимаешь, что делаешь.
Повреждение файловой системы
Повреждение может возникнуть как из-за сбоя питания, так и, опять же, некорректных действий пользователя и/или программ, например, при установке нового дистрибутива ты случайно удалил не тот раздел, или программа установки затерла суперблок.
Рассмотрим первую ситуацию (сбой питания) для ext4. В общем-то, эти методы работают при любой вышеперечисленной ситуации. Если система вообще не стартует, нужно загрузиться с LiveCD и по возможности скопировать образ раздела. Затем набираем в консоли следующую команду (предполагается, что ФС находится на sda7):
$ sudo fsck.ext4 -f /dev/sda7
Если все хорошо, то fsck
будет задавать вопросы. Все нормально. Главное, чтобы их не было слишком много. Но если fsck
ругается на некорректный суперблок… то и тут не стоит отчаиваться. Для начала узнаем, в каких блоках находятся резервные суперблоки, для чего используем стандартную команду mkfs.ext4
:
$ sudo mkfs.ext4 -n /dev/sda7
Команда эта, как правило, создает новую файловую систему и во время этой процедуры пишет местонахождение резервных суперблоков. Нам, разумеетcя, не надо создавать ФС. Но запуск с опцией -n ее и не создает, а всего лишь показывает процесс создания — а заодно и выводит список резервных суперблоков (он, в свою очередь, зависит от размера блока). Допустим, размер блока у нас равен 4 Кб. Тогда мы снова задаем команду fsck.ext4
:
$ sudo fsck.ext4 -f -b 32767 /dev/sda7
Опция -b указывает резервный суперблок, список которых мы получили из вывода предыдущей команды.
Если же и это не помогает (или хочется ручками попробовать восстановить), тогда пришло время для тяжелой артиллерии. В качестве таковой выступает связка утилит dumpe2fs
,tune2fs
и debugfs
. Их описание выходит за рамки данной статьи, но не упомянуть их я не могу. Кроме того, у команды mkfs.ext4
есть ключ '-S', который инициализирует только суперблок и группы блоков, но не таблицы инодов. После этого нужно запустить fsck
. При использовании этого способа помни — размер блока должен совпадать со старым, иначе шансы на восстановление значительно уменьшатся.
В случае с Btrfs набор утилит для восстановления очень и очень скуден. Тем не менее некоторые средства все же имеются. Опишу опции монтирования, относящиеся к восстановлению:
- опция монтирования recovery (доступна начиная с ядра 3.2) позволяет Btrfs при сбое сканировать предыдущие корни бинарных деревьев и по возможности использовать первый неповрежденный;
- degraded — для систем на нескольких устройствах (RAID-массив средствами Btrfs). Если одно устройство по каким-то причинам недоступно, эта опция позволяет смонтировать ФС и добавить новое устройство;
- skip_balance (доступна с ядра 3.4) отключает балансировку данных и метаданных. Использование этой опции имеет смысл, если питание было отключено внезапно и у тебя опять же ФС на нескольких устройствах — для ФС на одном устройстве операция балансировки не имеет смысла.
В FreeBSD fsck_ufs
для указания резервного суперблока принимает тот же параметр -b', что и в Linux. А вот у утилиты newfs
, в отличие от ее аналога mkfs.ext4
, для просмотра информации о создаваемой ФС без фактического ее создания используется ключ '-N'. Ключа, аналогичного описанному выше '-S', нет вообще. Для ручного восстановления используй аналогичную связку из утилит dumpfs
, tunefs
и fsdb
.
Для ZFS ситуация с утилитами восстановления хотя и более печальная, чем в случае с классическими ФС, но с Btrfs несравнима. И это при том, что субъективно Btrfs куда более сырая. Команды fsck
в ней нет, но ее ближайшим аналогом служит команда zpool scrub
, которая проверяет контрольные суммы всех занятых блоков пула. Для просмотра информации в уберблоке (примерном аналоге суперблока) используется утилита zdb
. В случае критического повреждения пула используй команду zpool clear -F
.
Установка неизвестного ПО
Действия в этой ситуации зависят от того, как именно ты ставил это ПО и загружается ли система вообще. Если система не загружается, в случае Ubuntu имеет смысл загрузиться с LiveCD и, подмонтировав корневую ФС, сделать chroot:
# mount --bind /proc /media/ubuntu-root/proc
# mount --bind /sys /media/ubuntu-root/sys
# mount --bind /media/ubuntu-root/dev
# chroot /media/ubuntu-root
Затем просмотреть, если ты ставил это неизвестное ПО с репозитория, список пакетов, которые недавно были установлены, для чего открыть файл /var/log/apt/history.log
и с помощью apt-get
удалить данный пакет. Если же ты устанавливал из исходных кодов, а система не загружается даже в однопользовательском режиме, скорее всего, ты установил какой-то модуль ядра, который прописался в initramfs
. Чтобы от него избавиться, посмотри каталог /etc/initramfs-tools/
, в частности файл modules
. После устранения подозрительных строк обнови initramfs
:
# update-initramfs -k all -u
Если система все же загружается в однопользовательском режиме, значит, дело в каком-то init-скрипте. Для просмотра свежесозданных файлов в каталоге /etc/init.d/
используй команду ls -t
, затем, после обнаружения службы, отключи ее с помощью команды update-rc.d имя_службы purge
. Затем перейди в каталог сборки и попробуй дать команду make uninstall
. Не факт, что сработает, но попытаться стоит.
Проблемы с видеодрайвером
Эти проблемы относятся к проприетарным драйверам. Разумеется, сейчас они возникают довольно редко, но все же возникают. Рассмотрю, например, ситуацию, когда вместо нормального изображения драйвер NVIDIA после запуска показывает по центру монитора полосу примерно в половину ширины экрана с прерывистыми диагональными линиями на ней. Если после ее появления переключиться на консоль и обратно, изображение нормализуется. Для исправления этой ситуации нужно принудительно выставить графический режим путем добавления параметра ядра. В файле /etc/default/grub
добавляем в переменную GRUBCMDLINELINUX_DEFAULT параметр vga=0x314. Должна получиться следующая строка:
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash vga=0x314"
Не забываем перегенерировать грабовский конфиг:
$ sudo update-grub
Еще одна проблемная ситуация может возникнуть, если драйвер неверно определяет разрешение монитора. Для ее решения есть два пути. Первый — добавить следующие строчки в файл /etc/X11/xorg.conf
в секцию Screen:
SubSection "Display"
Depth 24
Modes "1920x1200"
EndSubSection
Разрешение, естественно, нужно подставить желаемое. Но файл xorg.conf
считается устаревшим, поэтому рекомендую использовать комбинацию ~/.xprofile
и команды xrandr
. Создай файл ~/.xprofile
со следующим содержимым:
xrandr --output VGA-0 --mode 1024x768 --rate 60
Конечно, в твоем случае опция --output (как и разрешение) может отличаться. Чтобы узнать точно, куда подключен монитор, набери xrandr
без параметров.
LiveCD для восстановления системы
Cуществует несколько LiveCD-дистрибутивов для восстановления системы. Кратко опишу два из них.
Grml — LiveCD, основанный на Debian. Поддерживает как x86-, так и x64-системы. Может быть установлен на флешку. Из особенностей:
- По умолчанию в качестве оболочки используется ZSH, а в качестве WM — Fluxbox.
- USB-установка поддерживает сохранение конфигов (на флешке при этом нужно создать два раздела).
- Есть пакет sleuthkit, предназначенный как для восстановления данных, так и для компьютерных криминалистов.
SystemRescueCD основан на Gentoo. Последняя его версия, 3.8.0, выпущенная в сентябре этого года, имеет следующие особенности:
- Ядра как x86, так и x64, причем двух версий — Standard (3.4.62) и Alternative (3.10.12).
- В качестве рабочего стола используется Xfce.
- Помимо Linux, в меню загрузки имеются также некоторые образы дискет, например MHDD.
Все это добро умещается на 420 Мб.
Заключение
В этой статье я попытался описать самые частые и наиболее пугающие проблемы, которые могут возникнуть при работе в современных дистрибутивах Linux и FreeBSD. По сравнению с тем, что было раньше, этот список заметно поубавился. Тем не менее я не описал проблем, связанных с железом (видеодрайверы не в счет), — во-первых, потому, что оно у всех разное, а во-вторых — их нужно по возможности предотвращать, иначе, когда они себя проявят, уже будет поздно.