Не было печали, апдейтов накачали (Arch)
По мотивам этого поста.
Про 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 — до лучших времен.
Если с момента последнего обновления прошёл, допустим, месяц — то итеративно делим временной промежуток пополам. Сперва откатываемся на полмесяца назад. Если проблема исчезла — то обновляемся на четверть месяца вперед, если нет — то четверть месяца назад. И так далее.
Определение пакета-виновника
Итак, допустим что у нас обновилось 20 пакетов, и система сломалась.
Откатываемся назад на сутки — проблема осталась.
Откатываемся ещё на сутки — осталась.
Ещё на сутки — о, исчезла!
Возвращаем на место оригинальный mirrorlist и выполняем pacman -Syu.
Виновник совершенно точно находится среди пакетов, которые предложит обновить пакман, а число этих пакетов минимально возможное, поскольку мы откатились насколько возможно недалеко —, а именно на трое суток назад.
Допустим, пакман предлагает обновить три пакета: 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 следующего кандидата.
Пункт, который должен быть первым
А чей, собственно говоря, баг? Данная статья посвящена проблемам на уровне всего дистрибутива. Нет никакого смысла откатываться на старые версии пакетов, если проблема не вызвана их обновлениями. Поэтому первое, что делаем — это гуглим ошибку всеми возможными способами, настроив выдачу только на свежие записи. Если проблема общая — то с огромной вероятностью вы наткнетесь на свежий тред на каком-нибудь официальном форуме дистрибутива, где узнаете все подробности — точную дату проблемного обновления, имя проблемного пакета, и даже технические причины (что, собственно, сломалось под капотом).