По мотивам этого поста.
Про Archlinux ходит множество слухов, в том числе не совсем правдивых. В частности, устоявшееся общественное мнение говорит, что Арч часто ломается при обновлениях, так как bleeding edge. На практике это это одна из самых живучих и ремонтопригодных систем, которая может жить годами без переустановок, при этом обновляясь чуть не каждый день.
Иногда, около одного-двух раз в год, проблемы всё-таки возникают. Какой-нибудь злостный баг умудряется просочиться в репозитории, после обновления система ломается, и вы как пользователь мало что можете с этим сделать — надо откатываться.
Ситуация
С очередным обновлением всё ломается к хренам собачьим. Уровень возможных проблем варьируется от "шрифты стали некрасивые" до "перестала работать сеть", а то и "ядро не видит дисковые разделы". Многие пользователи Арча умеют справляться с этой проблемой так или иначе, а в этой статье я расскажу как это делаю я.
Возврат контроля над системой
Для проведения ремонтных работ нам нужна консоль и работающая сеть. Если есть — хорошо. Если нет — есть простой и быстрый способ гарантированно их получить. Грузимся с загрузочной флешки, монтируем наши дисковые разделы, чрутимся в систему:
arch-chroot /mnt
Всё, мы в консоли нашей системы, и у нас есть сеть.
А наличие загрузочной флешки в арсенале арчевода — практически обязательно.
Алгоритм ремонта
- Убеждаемся, что проблема нерешаема своими силами
- Определяем виновника проблемы и дату проблемного обновления
- Подменяем /etc/pacman.d/mirrorlist
- Выполняем pacman -Syyuu
Система отремонтирована!
Как это работает
Существует специальный сервер обновлений под названием Arch Linux Archive (ранее он назывался Arch Linux Rollback Machine), в котором хранятся "слепки" всех репозиториев на каждую отдельную дату.
Желаемую дату можно выбрать, специальным образом задав имя сервера в файле mirrorlist. Проще всего старый файл забэкапить, создать новый и добавить туда единственную строчку (в примере задано 1 декабря 2017г)
##
## Arch Linux repository mirrorlist
## Generated on 2042-01-01
##
Server=https://archive.archlinux.org/repos/2017/12/01/$repo/os/$arch
После чего команда pacman -Syyuu принудительно обновит базу данных пакетов на ту, которая соответствует выбранной дате, и принудительно переустанавливает все пакеты в системе, версии которых не соответствуют этой дате.
Наша задача — определить ближайшую дату, откат на которую даёт рабочую систему, выяснить какие пакеты обновились на следующий день, и выяснить, какой из этих пакетов вызвал поломку.
Приступим!
Определение нужной даты
Если система обновлялась не очень давно, можно пошагово уменьшать дату в mirrorlist, каждый раз выполняя pacman -Syyuu и проверяя, не исчезла ли проблема. Плюсом такого подхода является то, что можно с высокой вероятностью сразу вычислить конкретный пакет и добавить его в /etc/pacman.conf в строчку IgnorePkg — до лучших времен.
Если с момента последнего обновления прошёл, допустим, месяц — то итеративно делим временной промежуток пополам. Сперва откатываемся на полмесяца назад. Если проблема исчезла — то обновляемся на четверть месяца вперед, если нет — то четверть месяца назад. И так далее. Этот способ позволяет определить точный момент сбоя, который произошёл в течение последнего года, всего за 9 смен даты.
Определение пакета-виновника
Итак, допустим — мы не обновлялись уже неделю, pacman сообщает что есть 200 необновленных пакетов. После обновления система ломается.
Откатываемся назад на сутки, несколько пакетов "обновляются" до более ранней версии. Проверяем — система все ещё сломана.
Откатываемся ещё на сутки, ещё несколько пакетов снижают версию. Система сломана.
Ещё на сутки, очередные три пакета "обновляются" наоборот и ура, проблема исчезла!
Теперь мы точно знаем, что виноват один из этих трех пакетов. Допустим, это linux, linux-headers и gnome-shell. Так как linux-headers тянутся вслед за linux, их в расчёт не берем, это зависимость. Так что у нас всего два варианта.
Далее мы поодиночке добавляем кандидатов в /etc/pacman.conf.
Начнём с пакета linux:
# Pacman won't upgrade packages listed in IgnorePkg and members of IgnoreGroup
IgnorePkg = linux
#IgnoreGroup =
После чего обновляем систему через pacman -Syu и смотрим, не исчезла ли проблема. Если она исчезла — то как раз потому, что пакет-виновник записан в pacman.conf как запрещенный к обновлению. Если не исчезла — снова откатывается на рабочую систему, вписываем в IgnorePkg следующего кандидата и повторяем цикл.
Пункт, который должен быть первым
А чей, собственно говоря, баг? Данная статья посвящена проблемам на уровне всего дистрибутива. Нет никакого смысла откатываться на старые версии пакетов, если проблема не вызвана их обновлениями. Поэтому первое, что делаем — это гуглим ошибку всеми возможными способами, настроив выдачу только на свежие записи. Если проблема общая — то с огромной вероятностью вы наткнетесь на свежий тред на каком-нибудь официальном форуме дистрибутива, где узнаете все подробности — точную дату проблемного обновления, имя проблемного пакета, и даже технические причины (что, собственно, сломалось под капотом).
Возьмем пример выше. Допустим, мы выяснили, что наша система не грузится в графический режим после обновления пакета gnome-shell до версии 3.26.2
Что делать дальше?
Сперва делаем, чтобы система работала — откатываемся на дату на день раньше вредного обновления и добавляем gnome-shell в IgnorePkg (как вариант — добавить всю группу gnome в IgnoreGroup, чтобы гном не обновлялся частично).
Далее пытаемся найти в гугле ответ на вопрос — "это моя личная проблема или у других тоже так?" Если такой проблемы в интернете не обнаружилось — это может быть признаком того, что баг слишком свежий. Ждем для уверенности несколько дней, иногда повторяя поисковые запросы в разных сочетаниях. Если проблема в том, что проблемный пакет действительно пролез в репозитории — она обязательно вылезет в интернете! У арча огромная пользовательская база, и люди будут писать багрепорты и задавать вопросы на форумах.
Если в течение нескольких дней вы не видите никаких упоминаний о проблеме — у меня для вас плохие новости. Систему вы с вероятностью, близкой к 100%, сломали сами. Вспоминайте свои действия, анализируйте логи, разбирайтесь что произошло. Вообще, такой случай (когда какое-то обновление приводит к поломке, но это не баг) характерно для ситуаций, которые всегда освещаются в новостях в заголовком "при обновлении требуется ручное вмешательство". Такое случается, когда очередное обновление привносит настолько серьезные изменения в систему, что средствами самого обновления корректно это осуществить не удаётся.