えんでぃの技術ブログ

えんでぃの技術ブログ

ネットワークエンジニアの視点で、IT系のお役立ち情報を提供する技術ブログです。

rsync+TimeshiftによるLinuxシステム・データバックアップ方法の紹介

sync

Icons made by Freepik from www.flaticon.com

前の記事

Linux のシステムバックアップツールとして、Timeshift を紹介しました。

Timeshift の特徴と使い方
endy-tech.hatenablog.jp

Timeshift の詳細
endy-tech.hatenablog.jp

お伝えしたいこと

Timeshift は優秀なシステムバックアップ手段ですが、2つの弱点があります。

  • Timeshift がシステムバックアップに特化しており、データバックアップには別製品を利用するのが推奨されていること
  • Timeshiftが発行するrsyncコマンドは -H が指定されていないため、コピー元のハードリンクの関係性を保持しないこと

それらの弱点を補強する手段として、rsyncコマンドの使い方を紹介します。

なお、Timeshift に全く興味のない方でもrsyncのオプションは参考にしていただけると思いますので是非ご覧ください!

今回実現したいバックアップ構成

今回は、2種類のバックアップを使い分けます。
それぞれ長所と短所があるのですが、両方実行することで補えるようになっています。
ここでは概要のみ示します。
詳細については、(参考) Timeshift と rsync の違いの詳細で紹介します。

比較軸 方式1 方式2
バックアップツール Timeshift (GUI) rsync (コマンド)
実行間隔 定期自動実行 不定期手動実行
世代管理 する しない
バックアップ先 同一ディスクの別パーティション (/home) 外付けHDD
コピー元のハードリンク 保持する 保持しない

方式1 のTimeshiftは、システムバックアップを定期的かつ高頻度に実行します。
不意のシステム不具合が発生した時に、ロールバックするために使います。
ロールバック先が比較的最近のデータになるので、ロールバック時の影響範囲が少なくて済むのが利点です。

方式2 のrsyncは、システムバックアップとデータバックアップの両方を不定期かつ低頻度に実行します。
外付けHDDにバックアップを取得するので、ディスク故障時の復旧にも対応できます。
またハードリンクを保持してのバックアップが可能なので、システム復旧時においてもTimeshiftより理想的な復旧手段となります。
ただし、バックアップ頻度が少ないため、データ損失の範囲が大きくなりがちな点はTimeshift とトレードオフになります。

なお、以下の条件を両方満たす方は方式2のrsyncのみに振り切って、rsyncコマンドをanacronで定期実行する方式も良いと思います。

  • 常時マウント可能な外部ディスクを持っている (例えばNASNFSストレージを持っているか、SSHでリモートサーバにrsyncできる環境など)
  • 複数世代のバックアップが必ずしも必要ではない (複数世代の自力実装は作り込みに労力がかかります)

(方式1) Timeshift による定期システムバックアップ

Timeshift の使い方については、前回の記事を参照してください。

endy-tech.hatenablog.jp

(方式2) rsync による不定期全体バックアップ

バックアップ取得コマンド

以下のコマンドでバックアップを実行します。

sudo rsync -a -ADHRSX -vi --delete --force --stats --delete-excluded \
--exclude-from=/home/stopendy/Documents/backup/exclude.list \
/ \
/run/media/stopendy/toshiba_ext/pc/

以下、補足です。

  • 今回はシステムバックアップとデータバックアップを同時に取得しています
  • データのみバックアップを取りたい場合はコピー元ディレクトリを / から /home に変更します
  • コピー先の/run/media/stopendy/toshiba_ext/pc/は、外付けHDDを表しています

オプションの意味

Timeshift が発行しているコマンドをベースに、以下のアレンジを加えました。

  • ファイル属性保持のオプション (-AHX) の追加
  • 画面出力の簡素化 (-ii-i)
  • ログ出力オプション (--log-file) の削除
  • 世代管理用のオプション (--link-dest) の削除

各オプションの意味は、以下の通りです。

オプション 意味
-a, --archive -rlptgoD と同等。
-A, -H, -X は含まない
-r, --recursive ディレクトリ配下もコピーする
-l, --links シンボリックリンクをそのままコピーする
一方で-L, --copy-linksを指定すると、リンクを追跡してファイルの実体をコピーする
-p, --perms パーミッションを保持する
-t, --times 更新時刻を保持する。
ファイルのタイムスタンプが同じだった場合にコピーをスキップさせたい場合は、必須のオプション
-g, --group 所有グループを保持する
-o, --owner オーナーユーザーを保持する
-A, --acls ACLを保持する
-D --devices --specials と同義
--devices バイスファイル (/dev/*) も送れるようにする
--specials 特殊ファイル (named sockets, fifo など) も送れるようにする
-H, --hard-links ハードリンクを保持する (コピー元でinodeが等しいファイルの組み合わせを見つけたら、コピー先でも同じinodeになるようにする)
-R, --relative 送信元として指定したディレクトリ階層を保持してコピーする。例えばrsync a/b cを実行すると、c/bにファイルが生成するが、rsync -R a/b cを実行すると、c/a/bにファイルが生成する。今回はコピー元のパスが/なので意味はない
-S, --sparse スパースファイルを認識し、スパースファイルとしてコピーする
-X, --xattrs 拡張ファイル属性を保持する
v, --verbose より詳細に画面/ログ出力する
-i, --itemize-changes 変更点のあったファイルを一覧表示する。
-iiのように繰り返すと、変更されていないファイルも一覧表示する
--delete バックアップ先のディレクトリ内のファイルで、対応するバックアップ元のディレクトリに存在しないものがあった場合、そのファイルを削除する
この挙動はバックアップ元のパスにディレクトリを指定した場合のみ有効となる
--force バックアップ先の空でないディレクトリ名とバックアップ元のファイル名が同じだった場合、ディレクトリを削除してファイルをコピーする
--stats コピー完了後に表示される統計値をより詳細にする
--delete-excluded --excluded--exclude-fromなどによってコピー対象から除外されたファイルも、コピー先に存在した場合は削除する
--exclude-from=<FILE> コピー対象から除外するファイル・ディレクトリの一覧を<FILE>から読み取る。
コマンドラインに直接除外条件を書く場合は、--exclude=<PATTERN>を使う

除外リスト

除外リストの中身

--exclude-from オプションに指定したexclude.listは、以下のような中身になっています。
リストの書きっぷりは環境によって若干変わります。
/home 配下のユーザー名を変えたり、条件を足し引きしたり、一部をワイルドカード (*) で置き換えることで、他の環境にもマッチする形にアレンジできると思います。

#####################
# For System Backup (From Timeshift)
#####################
- /dev/*
- /proc/*
- /sys/*
- /media/*
- /mnt/*
- /tmp/*
- /run/*
- /var/run/*
- /var/lock/*
- /var/lib/docker/*
- /var/lib/schroot/*
- /lost+found
- /timeshift/*
- /timeshift-btrfs/*
- /data/*
- /DATA/*
- /cdrom/*
- /sdcard/*
- /system/*
- /etc/timeshift.json
- /var/log/timeshift/*
- /var/log/timeshift-btrfs/*
- /swapfile
- /snap/*
- /root/.thumbnails
- /root/.cache
- /root/.dbus
- /root/.gvfs
- /root/.local/share/[Tt]rash
- /home/*/.thumbnails
- /home/*/.cache
- /home/*/.dbus
- /home/*/.gvfs
- /home/*/.local/share/[Tt]rash
- /root/.mozilla/firefox/*.default/Cache
- /root/.mozilla/firefox/*.default/OfflineCache
- /root/.opera/cache
- /root/.kde/share/apps/kio_http/cache
- /root/.kde/share/cache/http
- /home/*/.mozilla/firefox/*.default/Cache
- /home/*/.mozilla/firefox/*.default/OfflineCache
- /home/*/.opera/cache
- /home/*/.kde/share/apps/kio_http/cache
- /home/*/.kde/share/cache/http
- /var/cache/apt/archives/*
- /var/cache/pacman/pkg/*
- /var/cache/yum/*
- /var/cache/dnf/*
- /var/cache/eopkg/*
- /var/cache/xbps/*
- /var/cache/zypp/*
- /var/cache/edb/*
#- /home/stopendy/**
#- /root/**
#- /home/*/**

#####################
# /home/
#####################
# /home/stopendy/, /home/*/.*
+ /home/stopendy/Applications/
+ /home/stopendy/Desktop/
+ /home/stopendy/Documents/
+ /home/stopendy/Music/
+ /home/stopendy/Pictures/
+ /home/stopendy/Videos/

+ /home/*/.config
+ /home/*/.dir_colors
+ /home/*/.local/
+ /home/*/.local/bin/***
- /home/*/.local/*
+ /home/*/.ssh/

- /home/stopendy/*
- /home/*/.*

- /home/*/.config/biscuit/
- /home/*/.config/Code/
- /home/*/.config/google-chrome/

# /home/**/*.log
+ /home/*/Documents/**/*.log
- /home/**/*.log

# /home/timeshift/
- /home/timeshift/

#####################
# /root/
#####################
+ /root/.config
+ /root/.dir_colors
+ /root/.local/
+ /root/.local/bin/***
- /root/.local/*
+ /root/.ssh/

- /root/*
- /root/.*

- /root/.config/biscuit/
- /root/.config/Code/
- /root/.config/google-chrome/

除外リストの設計思想

前半のシステムバックアップに関係する部分は、Timeshift で使っているexclude.list をほぼ流用しています。

後半のデータバックアップに関係する部分は、ホームディレクトリ直下の隠しフォルダ配下のバックアップ対象を厳選しています。
特に、ブラウザやVSCodeのキャッシュファイルが大量にあって邪魔だったので明示的に除外しています (biscuit, Code, google-chrome)。

除外リストの文法

除外リストの文法を簡単にまとめました。
公式情報は、man rsync の「FILTER RULES」セクションに書いてあります。

  • コピー対象から除外するディレクトリを列挙する
  • 先頭に+を記載すると、「このファイルを含める」という意味になる (プラス記号の後に半角スペースが必要)
  • 先頭に-を記載すると、「このファイルを除外する」という意味になる。この記号は省略しても同じ意味 (マイナス記号の後に半角スペースが必要)
  • 先頭に#を記載すると、コメント行扱いとなって無視される
  • *は1文字以上 (スラッシュを含まない) にマッチする
    • /a/*は、/a/bにマッチするが、/a/a/b/cにはマッチしない
  • **は1文字以上 (スラッシュを含んで良い) にマッチする
    • /a/**は、/a/b/a/b/cにマッチするが、/aにはマッチしない
  • ***は0文字以上 (スラッシュを含んで良い) にマッチする
    • /a/***は、/a/a/b/a/b/cの全てにマッチする
  • 除外条件と含める条件の評価順は、--exclude--includeと同じ考え方となる
    • 例えば、a/b/cにあるファイルcは、aa/ba/b/cの全てが除外扱いではない場合のみコピーされる
    • 除外リストの複数条件に一致する場合、リストの上に書いてある方が優先される
    • 詳細はてっく煮ブログが参考になる

除外リストの動作確認

exclude.listを更新する際は、テスト実行モード (-n, --dry-run) とバックアップ対象ファイルの全表示 (-ii) も一緒に指定しつつrsyncを繰り返し実行すると便利です。
出力されたバックアップ対象ファイルをチェックすることで、exclude.listの定義にミスがないかを事前に確認することができます。
今回の例では、以下がテストコマンドになります。

sudo rsync -n -a -ADHRSX -vii --delete --force --stats --delete-excluded \
--exclude-from=/home/stopendy/Documents/backup/exclude.list \
/ \
/run/media/stopendy/toshiba_ext/pc/

rsync バックアップからの復旧

注意事項

復旧手順は、以下の条件で検証しました。

  • KVM上の仮想マシンFedora 32 + Cinnamon Desktop など、模擬的にパソコン環境を再現
  • rsync でシステム・データバックアップ
  • Fedora 33 にバージョンアップ
  • データ復旧確認
    • ファイルを1つ削除して、データ復旧コマンドを実行
    • 再ログインし、最低限の動作確認を実施
  • システム復旧確認
    • システム復旧コマンドを実行し、OS再起動
    • カーネルやパッケージのバージョンが元に戻ったことを確認
    • 最低限の動作確認を実施

ご覧の通り、擬似環境で最低限の確認しかしていません。
情報としては参考になると思いますが、実際に使う前に必ず手元のVMなどでも検証するようにしてくださいね。

復旧コマンドの基本的な考え方

以降のセクションでシステム復旧、データ復旧、システム+データ復旧の3つの例を紹介します。

3つの例に共通して、復旧の際はバックアップ取得コマンドを部分的に変更して実行します。
基本的には引数を入れ替えて、--delete-excluded-R を外します。
単純にコピー元とコピー先の引数を入れ替えただけで実行すると、大事故に繋がる可能性がありますのでご注意ください。
必ず検証してくださいね。

(1) システムの復旧

システム復旧コマンドは、バックアップコマンドをベースに以下のように作りました。

  • --delete-excluded-Rを外す
  • コピー元とコピー先の引数を入れ替える
  • --exclude-fromより手前に--exclude=/homeも入れることでデータフォルダを除外する

検証したところ、OSをISOファイルから起動するレスキューモードからシステム復旧する必要は必ずしもありませんでした。
実際にシステムディスクがマウントされた状態で復旧してみたら、/var配下の1ファイルがエラーになっただけでしたので、このやり方でも問題ないようです (環境にもよるかもしれません)。
とはいえ、「やはり念のためレスキューモードから実行したい」と思った場合は、(参考) レスキューモードからの起動を参考にしてみてください。

システムをリストアした後は、必ずOS再起動してください。
大抵のファイルはrsyncで巻き戻されますが、メモリや/procなどの情報はそのままです。
システム復旧は、OS再起動まで実行して初めて完了するとご認識ください。

# システム復旧
sudo rsync -a -ADHSX -vi --delete --force --stats \
--exclude=/home  \
--exclude-from=/home/stopendy/Documents/backup/exclude.list \
/run/media/stopendy/toshiba_ext/pc/ \
/

(2) データの復旧

データ復旧コマンドは、バックアップコマンドをベースに以下のように作りました。

  • --delete-excluded-Rを外す
  • コピー元とコピー先の引数を入れ替えつつ、対象がデータディレクトリとなるように変更
  • 念のため--deleteを除外した (必要なら再度追加してもよい)
  • コピー先が/homeである場合、コピー元はxxx/home/のように末尾に/を入れること!
    • rsyncはコピー元に/を入れると、ディレクトリ内の全ファイルをコピー対象とする
    • コピー元に/が入っていない場合、ディレクトリ自体をコピー対象とする
    • /の有無でコピー対象の考え方が変わるので、-nでテストしつつ慎重に判断すること

データのみ復旧する場合は、システム復旧時とは異なりシングルユーザーモードで実行する必要はありません。
ただ設定ファイルを強制的に書き換えることで、ユーザープロセスがクラッシュすることがあります。
例えば、私の環境では日本語入力を管理するiBusデーモンがクラッシュし、一時的に日本語入力ができなくなりました。
これらのプロセスを復旧するためにも、/home配下のデータ復旧後は最低でもユーザーの再ログインは実施してください。

# データ復旧
sudo rsync -a -ADHSX -vi --force --stats  \
--exclude-from=/home/stopendy/Documents/backup/exclude.list \
/run/media/stopendy/toshiba_ext/pc/home/ \
/home

(3) システムとデータの復旧

基本的には、上述の(1) システムの復旧(2) データの復旧をそれぞれ実行してください。
同時に実行することはおすすめしません。
システム復旧とデータ復旧は、実行したい場面も目的もコマンドラインオプションも色々異なります。
たまたまそれら全てが一致することもあるかもしれませんが、手順がややこしくなるので辞めておいたほうが良いと思います。

以上で3記事に渡るTimeshift と rsync によるバックアップ構成の紹介は終了となります。
ご覧いただき、ありがとうございました。

以下に補足情報が続きます。

(参考) Timeshift と rsync の違いの詳細

Timeshift と rsync を使い分けているのは、それぞれの短所を補い合うためです。
概要は上述の今回実現したいバックアップ構成にて紹介しましたが、本セクションではより詳細に紹介します。

実行間隔

Timeshift は定期的にバックアップを取得します (日次や週次など)。
一方で、rsync不定期 (恐らく3ヶ月〜半年に1度程度) でバックアップを取得する想定です。

不意にシステムが起動しなくなってしまったときは、Timeshift により最近のバックアップデータから復旧させることでデータ損失を最小限にできます

なお、rsyncのバックアップ実行タイミングは以下の想定です。

  • システムに問題が発生するリスクの高い作業の直前
    • OSバージョンアップ
    • パッケージ一括更新 (sudo dnf upgrade)
  • ディスク故障に備えたユーザーデータのバックアップ (半年に一度程度)

世代管理

先に一般論を書きます。
バックアップの定期実行は、ある程度頻度を高くしないと復旧時のデータ損失が大きくなりますが、一方でデータの保管期間をある程度長くしないと復旧が間に合わずに手遅れになるリスクが高まります。

ここでツールの話に戻りますが、Timeshift はバックアップを複数世代持ちます。
rsync はバックアップを1世代のみ保管し、バックアップの度に同一ディレクトリに差分ファイルを追加・削除する動きです。

Timeshift は差分バックアップを複数世代持つことで、バックアップ取得間隔を短く保ちつつも、バックアップの保管期間を長くすることができます。
これは定期的にバックアップする用途として、重要な特徴です。

例えばバックアップを日次・週次で実行し、日次バックアップを3世代、週次バックアップを2世代保管する設定にしていたとします。
その場合は、基本的には当日・前日・前々日のデータに戻すことで最低限の損失でシステムを復旧させることができます。
対応が遅れてしまった場合でも、1、2週間前のバックアップから復旧させれば、多くの場合は不具合が発生する前まで戻せます。

普段遣いのLinux PC は「作業の度に手動バックアップ、作業後に正常性確認 (または常時監視)、異常を検知したらすぐに復旧」とは中々いかないと思います。
こういった定期バックアップ + 世代管理の仕組みがあることで、より快適にLinux を扱えるようになります。

バックアップ対象

一般的には、システムバックアップとデータバックアップは分けるべきです。
例えばTimeshift によってユーザーデータも含めてバックアップを取得してしまうと、システムを復旧したい時にユーザーデータも巻き添えを食って古いデータで上書きされてしまいます。
従って、Timeshift はシステムの (/homeを除いた) バックアップのみ取得する構成としています。
これはTimeshift 公式でも推奨されている使い方です。

一方で、データバックアップの取得はrsyncで行います。
今回の構成では事情により、rsyncでシステムとデータ両方のバックアップを取得しています。
しかしrsyncの場合は、コマンドや除外リストを少し弄ることでシステムのみ復旧、データのみ復旧といった操作も容易にできるので、特に問題はありません。

rsync でシステムとデータの両方のバックアップを取得していることは、rsyncが外付けHDDにバックアップを取得していることや、ハードリンクを保持できることに関係します。
これらの事情については、この後のセクションで紹介します。

バックアップ先 (同一ディスク vs 外部ディスク)

バックアップを実行する際、当然ながらバックアップ先のファイルシステムはマウントされている必要があります。

Timeshift は定期的にバックアップを取得します。
その性質から、Timeshift のマウント先は常時マウントされていることが望ましいです。
私の環境ではPCの内蔵ディスクはメインの1本しかありませんし、NASNFSも持っていません。
常時マウントされているディスクは、コピー元と同じメインのディスクしかない構成です。
Timeshift はシステムのみ (/homeを除外する) のバックアップですので、バックアップ先として/homeを指定します。

バックアップ元とバックアップ先が同一のディスクだと、設定ミスやファイル破損には対処できますが、ディスク故障でデータが失われてしまいます。
そこで、外付けHDDの出番です。
データバックアップは、外付けHDDを接続してrsyncコマンドを実行することで不定期に取得します。
これにより、内蔵ディスク自体が故障しても外付けHDDから復旧できます。

コピー元のハードリンクを保持するか否か

Timeshift はシステムバックアップを取得しますが、実は完璧ではありません。
Timeshift が内部的に実行しているrsyncでは、-AHXが指定されていません。
これにより、Timeshift のバックアップから復旧した場合、以下のような制限を伴います。

  • バックアップ元のACLを保持しない (-Aの指定がないため)
  • バックアップ元のハードリンクを保持せず、複数ファイルのコピーとして扱われる (-Hの指定がないため)
  • バックアップ元の拡張ファイル属性を保持しない (-Xの指定がないため)

特に-Hの指定がないことが影響を大きくしています。
ハードリンクの関係性にあるファイル群は、本来それらのうちどれか1つを更新すれば、他のハードリンクにも変更が反映されます。
しかし、単純なファイルコピーではそうも行かず、全てのファイルをそれぞれ同様に更新する必要が出てきてしまいます。
Timeshiftユーザーでこのことが問題になっている話は聞いたことがありませんが、システムファイルではハードリンクが少なからず使われているので、この影響は小さくないと思います。

一方でrsyncは、当然ながらどのオプションを付与するか自分で選択できます。
rsyncコマンドを実行する際、-AHXオプションを指定することで、上記の問題を回避できます。

Timeshiftよりも低頻度ではありますが、不定期にrsyncでシステムバックアップも取得することで、ハードリンクに関わる問題を回避することがrsyncを使う目的の一つです。

(参考) rsync実行時のフラグの意味

rsync実行時、-i-iiを付与して実行すると変更対象のファイル一覧の左にフラグが付きます。
例えば.f.d などのフラグです。

ここではフラグの読み方を紹介します。
正式な情報は、man rsync--itemize-changes, -iセクション配下を参照してください。

フラグの基本的な書式は、YXcstpoguax です。

Y (1文字目) は、更新方法を表します(update types)。
Yが最も重要です。

フラグ 意味
. 更新なし
> ローカルへのファイルコピー
< リモートへのファイルコピー (SSHなどによって外部ホストにファイルコピーしたときのみこのフラグが付く)
c ファイル・ディレクトリの生成
h ハードリンクとして生成 (-H, --hard-linksオプション利用時のみ)
* *MESSAGE と表記され、その他の変更を表す。主に*deletingでファイルの削除を表す

X (2文字目) は、コピーされるファイルの分類です。

フラグ 意味
f ファイル
d ディレクト
L シンボリックリンク
D バイスファイル
S special file (named socket や fifo など)

cstpoguax (3文字目〜11文字目) は、変更の理由として検知されたファイル属性です。

フラグ 意味
c チェックサム
s サイズ
t,T t: 更新時刻 (要:-t, --times)
T: 更新時刻 (-t, --timesを指定しなかった場合のみ表示される)
p パーミッション (要:-p, --perms)
o オーナー (要:-o, --owner。要:特権付き (sudoなど) でのrsync実行)
g グループ (要:-g, --group。要:特権付き (sudoなど) でのrsync実行)
u,n,b u: アクセス時刻 (use time。要:--atimes)
n: 作成時刻 (要:crtimes)
b: アクセス時刻と作成時刻の両方(both)
a ACL
x 拡張ファイル属性 (extended attribute)

cstpoguax (3文字目〜11文字目) は、以下の文字で表現されることもあります。

フラグ 意味
. 変更なし
+ 全フラグ変更あり (大抵、ファイルやディレクトリ生成になる)
? 不明 (宛先のrsyncのバージョンが古い場合に表示されることがある)
※スペース 全て変更なし (.) の場合は、スペースで省略表記される

最後に具体例を示します。

フラグ 意味
.f.d 何もしない (差分なし)
>f..t...... ファイルコピー (ファイルの更新時間のみ差分)
.d..t...... 何もしない (ディレクトリの更新時間のみ差分)
*deleting ファイル削除 (--deleteオプションなどが指定されており、対応するファイルがコピー先に存在しないため)
>f.st.....x ファイルコピー (更新時刻とファイルサイズと拡張ファイル属性の差分)
cd+++++++++ ディレクトリ生成 (全部差分あり)

(参考) レスキューモードからの起動

RHEL8のドキュメントによると、レスキューモードとはsystemdの機能で提供されるものとLinux起動イメージファイルを利用するものの2種類ありますが、ここでは後者のイメージファイルを利用したレスキューモードのお話をします。

手順はFedoraをベースに紹介します。
Debian系など他のディストリビューションでは手順が異なる可能性もありますが、ご了承ください。

レスキューモードでは、OSインストール用のISOファイルやUSBを利用してOS起動します。
ルートファイルシステム上でプロセスが動作していない状態で各種操作ができます。

rsyncによるシステム復旧の文脈においてどの程度の意味があるかはわかりませんが、ご参考までに手順を記載しておきます。

まず、起動順序を通常のHDDよりもUSB、またはCDドライブなどを優先するようにBIOS/UEFI (VMの場合は仮想マシンのオプション) を設定しておきます。
その上で、起動用USBを物理サーバに挿すか、仮想サーバの場合はCDROMにOSインストール用のISOファイルを紐づけます。

その状態でOSを起動すると、コンソール画面に以下のようなメニューが表示されるので、Troubleshooting -->を選択します。

rescue1

そして Rescue a Fedora systemを選択します。

rescue2

レスキューモードの起動方法の選択肢が出てくるので、基本的には1) Continueを選択します。
ハードディスクのマウントやネットワークの起動など実施してくれるので色々と便利です。

もしこれらの自動起動箇所に不具合があるなどの理由で1. を選択できない場合には、3) Skip to shellを選択します。
このオプションは何もせずISOファイルの中身だけを使ってシェルを起動するので、基本トラブルが発生することはありません。

rescue3

1) Continue を選択した場合

このモードを選んだ場合、ディスク上にインストールされたLinuxを検知し、自動的に/mnt/sysrootにマウントします。
マウントオプションはrwで、読み書き可能です (ちなみに2を選んだ場合はroになります)。
また、NetworkManager.serviceも起動し、ネットワークも使用可能になります。

このモードを選んだら、後は簡単です。
mnt/sysrootchrootして、リストア作業を続行するのみです。
chrootコマンドは以下のコマンドで実行できます。
また、su -コマンドにより、必要に応じてrootユーザのログイン処理を読み込むことも可能です (プロンプト文字列が変わると思います)。
またこのモードではデフォルトでUSキーボードになっているので、お好みに応じてキーボードの言語をchroot前に変えておきます。

localectl set-keymap jp
chroot /mnt/sysroot
su -

外付けHDDからリストアしたい場合は、外付けHDDを手動でマウントする必要があります。
まずはマウントポイントを作成します。
私の環境では、以下のようになります。

sudo mkdir -p /run/media/stopendy/toshiba_ext/

続いて、マウントしたい外付けHDDのデバイスファイルを特定します。
fdisk -lで詳細情報を表示し、ディスクサイズなどをヒントにデバイスファイルを特定します。
今回は/dev/sda2でした。

特定が難しい場合は、usb-devicesコマンドも試してみましょう。
ManufacturerSerial Numberを元にusb-devicesの表示の中から目的のUSBデバイスは容易に特定できます。
そのUSBデバイスには、Product=External USB 3.0と書かれていました。
一方でfdisk -lにもDisk model: External USB 3.0と同様に書かれていましたので、これらを見比べれば確実に紐づけできます。

usb-devices
sudo fdisk -l

最後に、手動でマウントします。

sudo mount /dev/sda2 /run/media/stopendy/toshiba_ext/

以降は、(1) システムの復旧に従ってリストアを続行します。
リストアが完了したら、exitで抜けます。
するとOSが自動が再起動し、うまくいけば復旧しています。

仮想マシンの場合はshutdown -h nowで一度シャットダウンしてから、ISOファイルの取り外しや起動順序の設定戻しなどを対応します。

3) Skip to shell を選択した場合

自動マウントやネットワーク起動などの処理が一切行われず、直接シェルが起動します。
まずは、Linux Root Filesystem を手動で /mnt/sysroot にマウントします。

まずは、LVMを使える状態にします。
LVMをそもそも利用していない場合は、この工程をスキップして問題ありません。
lvdisplayコマンドでLogical Volume を表示します。
以下の情報から、Volume Group の名前がfedora_pcであることと、LV StatusがNOT availableであることがわかります。

$ lvdisplay
# 一部のみ表示
  LV Path                /dev/fedora_pc/root
  LV Name                home
  VG Name                fedora_pc
  LV Status              NOT available

lvchangeコマンドにより、LVを利用可能にします。
--activate yは、対象をAvailableにするという意味です。
その後の引数には、LV PathVG Nameを指定します。
VG Nameを指定すると、対象のVolume Group に紐づくLogical Volume に対して一括変更できて便利なので、今回はこちらを指定します。
再びlvdisplayを実行し、LV Statusavailableとなっていることを確認します。

lvchange --activate y fedora_pc
lvdisplay

次に、システムディレクトリをマウントします。
マウントディレクトリを作成し、マウントします。
mountコマンドに指定するデバイスファイルには、先ほどのlvdisplayで表示されたLV Pathを指定します。
最初にRoot File Systemからマウントしますが、他にもファイルシステムがある場合は同じ手順を繰り返します。

mkdir /mnt/sysroot
mount /dev/fedora_pc/root /mnt/sysroot

そしてchrootします。

chroot /mnt/sysroot
su -

あとは1) Continue を選択した場合と同じ手順です。

Linux PC関連まとめ

endy-tech.hatenablog.jp

まとめ

Timeshiftの弱点を補強するシステム・データバックアップ方法として、rsyncコマンドについてまとめました。
本来であればTimeshift が-AHXオプションに対応するようプルリクエストを送るか、自力でrsync定期実行 & 差分管理スクリプトを組むのが理想かもしれません。
しかし、自身のスキルでは理想を追うのが難しいため、現時点で実現できる仕組みとして今回のやり方を考えました。

皆さまにとっても参考になれば幸いです。