fedoraのsystem-upgradeが失敗して復旧させたメモ

この記事はLinuxのカレンダー | Advent Calendar 2022 - Qiitaの8日目の記事です。

会社にあるfedora 36のPCをfedora 37にアップグレードしようと思ってリモートからdnf system-upgradeでアップグレードしかけといたら何かしらの原因でアップグレードに失敗してて、それを復旧させるのに時間くらいかかったので防備録的に🥲

今回起きてた現象

root causeは何かしらの理由でdnf system-upgradeが失敗してたことなんだけど、その理由はもはやわからないのでこれによって発生してた現象のみを書くと次の3点でした。

  1. dnf・rpmコマンドでパッケージのインストールをしようとするときにsegvする(ファイルのdownloadなどは大丈夫だった)。
  2. fc36とfc37が中途半端に混在
  3. selinuxのラベルがおかしくなってた

復旧の流れ

  • リモートから接続できなかったのでまずは物理出社
  • 出社してPCを見てみたら電源が落ちてた
  • まずは電源オン
  • ログインできるし、ログイン画面もFedora 37のgnomeな感じだし、/etc/os-releaseとか/etc/fedora-releaseファイルもfedora 37になってる
  • ひとまずdistro-syncしてみる?と思って実行してみたらrpmファイルのインストールするときにsegvする
  • dnfのrepolistとかは使えるんだけど、インストール処理がだめっぽい
  • rpmはどうよ?と思ったけど、これも同様
  • この環境だけで復帰させるの無理じゃん😭
  • 会社にあるfedoraのライブCDを探したらfedora 32のCDがあったのでこれ使うかー
  • このPCはboot順番変更のメニュー出せるタイプなのかUEFI BIOSで起動順変える必要あるのかとか、どのキー押すのかまったく覚えてない😨
  • しょうがないので、ESC、F11、F12あたりを連打してUEFI BIOSに入れたのでDVDドライブから起動させる
  • ライブ環境が立ち上がったらディスク上にあるLVM領域の/を/mntにマウント
  • ライブCD(fedora 32)のdnfを使って/mntにマウントした環境をアップデートかけよう
  • dnfのオプションには--installroot=/mntと--releasever=37をつける
  • /etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-37-x86_64がないと言われるけどfedora 32なんだからそれもそうだね
  • /mnt/etcのほうにもなかった
  • feodra 36のノートPCのほうにはこのファイルはあるけどどうやってファイルを受け渡すか?
  • ノートPCのほうで/etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-37-x86_64を~/tmpとかにコピー
  • python -m http.server 8000で簡易的にhttpサーバを立ち上げてライブCDからcurlでファイルダウンロード
  • ダウンロードしたファイルは/etc/pki/rpm-gpg/と/mnt/etc/pki/rpm-gpgの両方に置いた
  • RPM-GPG-KEY-fedora-37-x86_64の問題は解決できたけど、一部のパッケージで検証に失敗する
  • dnfのオプションに--nogpgcheck追加
  • これで/mnt/環境にdnf updateをかけてみる
  • 成功したので/mntにchrootで入ってみる
  • docker-ce-stableとかの3rdパーティのリポジトリは無効にしてfedora.repoとfedora-updatesだけ有効にする
  • chrootで/mntに入ってdnf・rpmコマンドを試したらsegvしなくなってる!が、まだ問題はあった
  • repolistを確認するとリポジトリがfc36を見ている
  • releasever変数が36とされてるようだ
  • dnfのオプションで--releasever=37を付けても良かったんだけど、なんとなくsedでreleasever変数を37に置き換えた
  • distro-syncを試すとsystemdとかgnome-shellが依存関係の問題で削除されるとか言われてエラーになる
  • 元の環境であったdnf・rpmがsegvする問題はなくなったけど、system-upgradeが途中でエラーになったことでfc36とfc37が中途半端に混ざった状態っぽい
  • まあ、dnfは使えるようになったのでライブCD環境を終了して普通に起動してログイン
  • 起動したらyum.repo.dのほうは先ほどと同じ感じでfc37を見るように強制
  • rpm -qaでsystemdのパッケージを確認するとfc36とfc37の両方のパッケージが存在してる
  • dnfだと削除できないのでrpm -eでfc36・fc37が混在してるものはfc36のパッケージを削除
  • 全部消したところでdnfのdistro-sync
  • 成功したのでdnf update --refreshでさらに新しいパッケージへの更新もできた
  • yum.repo.dの3rdパーティのリポジトリも有効にしてupdateかけたり
  • カーネルはfc37版はインストール済みと言われるんだけど/bootにはfc36版しかない
  • カーネルもインストール状況が中途半端になってる感じだけど新しいバージョンがでればそれがインストールされて解決できるのでは?
  • という感じで、これはこのままにしておく
  • リモートからこのPCに入るためにはsshログインできる必要あるけど、ログインできないじゃん😭
  • クライアント側でこんなエラーメッセージが表示される
ssh client loop send disconnect

sshの-vオプションをつけるとさらにこんなメッセージが

openssh pledge filesystem full
  • dfでディスクの使用量見たけど全然余裕あるな
  • inode?と思ったけどこちらも問題なし
  • 検索するとアクセス権限の問題でもこのエラーメッセージは出るらしい
  • journalctlでログを見てみる
  • こんなログがでてるし、まさしくこれが原因でしょ
sshd_selinux_copy_context: setcon failed with permission denided
  • system-upgradeが途中で終わったことでselinuxのラベリングも中途半端になってるんじゃ
  • 今見えてる問題はsshdだけど他にもあるかもしれない
  • ラベリングし直すかということでファイルを作って再起動
touch /.autorelabel
  • ラベリングが終わってシステムが立ち上がったらsshログインしてみる
  • ログイン成功キタ━(゚∀゚)━!
  • virsh、dockerも動くか確認
  • これらもok
  • これでひとまず復旧完了として良いでしょということで復旧作業終了🥲

所感

このレベルの壊れ具合でも復旧させることができるトラブルシューティング能力はあるんだなって思ったけども、めんどくさいから勘弁してほしい。あとはやっぱライブメディアはあると便利。というかなかったら復旧できなかった。今回は再インストール無しに復旧させたけど、fedora 37のライブメディアがあったらクリーンインストールして再セットアップしたかもしれない。そっちのほうが確実だし。家なら最新のfedoraライブメディアは常にあるけど、会社にあったのがfedora 32だったので32をインストールしてから34 -> 36 -> 37という感じにアップデートさせるのも面倒だったというのもある🥲

同じ状況になる人はまずいないと思うけど、個々の現象に関してはこんな対応方法もあるということで防備録でした。

家に帰ったら自分からのクリスマスプレゼントがamazonさんから届いてた🍪