A/B Dual-Root na Arch Linux — Odporność na Awarie Zasilania
Posted on Thu 30 April 2026 in hardware
• [9 min read]
- Wstęp
- Architektura systemu
- Przygotowanie — Task 0: Backup /home
- Resize LVM — Task 1: Live USB
- Skrypt mark-root-backup-pending — Task 2
- Skrypt sync-root-backup — Task 3
- Skrypt restore-root-from-backup
- Pacman hook — Task 4
- Prompt w terminalu — Task 5
- Waybar — skrypty — Task 6
- Polkit i sudoers — Task 7
- Waybar — konfiguracja i CSS — Task 8
- Wpis systemd-boot — Task 9
- Diagnostyka i rekalibracja baterii — Task 10
- Kolejność wykonania
- Pliki projektu
Wstęp
Podczas aktualizacji systemu poleceniem yay -Syu nastąpiła awaria zasilania. Bateria MacBooka nie działa prawidłowo i nie utrzymuje laptopa przy życiu gdy nie jest podłączony do zasilania sieciowego. Część pakietów została zainstalowana tylko częściowo — w efekcie sway nie startował, a dbus odmawiał uruchomienia. Odzyskanie systemu wymagało bootu z zewnętrznego dysku USB i ręcznej reinstalacji uszkodzonych pakietów.
Rozwiązanie problemu opiera się na dwóch filarach:
- System A/B dual-root — dwa wolumeny LVM dla katalogu głównego. Backup jest synchronizowany dopiero gdy użytkownik potwierdzi że aktualizacja nie wywołała problemów. W razie awarii wystarczy restart i wybór wpisu Arch Linux (backup) w menu bootloadera, a następnie przywrócenie partycji root ze skryptu.
- Diagnostyka i rekalibracja baterii — identyfikacja przyczyny nagłych wyłączeń i procedura przywrócenia prawidłowej kalibracji BMS.
Architektura systemu
Układ LVM po implementacji:
nvme0n1p2 (LUKS2)
└── vg0 (446 G)
├── root 65 G aktywny system
├── root-backup 65 G zsynchronizowana kopia
├── swap 32 G
└── home 284 G
Oba wolumeny root są zaszyfrowane tym samym kontenerem LUKS2. Wspólny jest również wolumin swap (używany do hibernacji). Katalog /home jest oddzielny i nie jest duplikowany — tworzony jest wyłącznie backup na zewnętrzny dysk.
Przepływ pracy po wdrożeniu
Normalny scenariusz (aktualizacja):
- Użytkownik uruchamia yay -Syu.
- Po zakończeniu transakcji pacman hook automatycznie stawia flagę /var/lib/sync-root-backup/pending z timestampem.
- Przy kolejnym otwarciu terminala pojawia się przypomnienie.
- W waybarze miga czerwona ikona ⚠.
- Użytkownik weryfikuje że system działa prawidłowo (sway, dbus, sieć).
- Dopiero wtedy uruchamia synchronizację — ręcznie lub kliknięciem ikony.
- Po synchronizacji flaga znika, ikona znika z waybara.
Scenariusz awaryjny (awaria podczas aktualizacji):
- System nie startuje prawidłowo po aktualizacji.
- Restart → menu bootloadera → Arch Linux (backup).
- System uruchamia się ze zsynchronizowanej kopii sprzed transakcji.
- Waybar wyświetla pomarańczową ikonę ⚠ BACKUP.
- Użytkownik klika ikonę lub uruchamia sudo restore-root-from-backup.
- Skrypt kopiuje root-backup → root i aktualizuje fstab.
- Restart → Arch Linux → system wróci do stanu sprzed awarii.
Stan ikon waybar w zależności od kontekstu:
| Sytuacja | Waybar | Shell |
|---|---|---|
| Na root, backup aktualny | brak ikony | cisza |
| Na root, backup nieaktualny | ⚠ migająca czerwona | [!] Uruchom: sudo sync-root-backup |
| Na root-backup | ⚠ BACKUP pomarańczowa | [!] Uruchom: sudo restore-root-from-backup |
Ograniczenia
Wspólny /boot (kernel + initramfs) oznacza że awaria podczas aktualizacji kernela lub mkinitcpio dotknie oba sloty. Ochrona obejmuje wyłącznie userspace: pakiety AUR, konfiguracje sesji, sway, dbus. Jest to świadome ograniczenie — awaria kernela jest rzadsza i możliwa do wykrycia od razu po restarcie.
Przygotowanie — Task 0: Backup /home
Przed operacją na wolumenach LVM należy zaktualizować kopię zapasową katalogu domowego. Dysk zewnętrzny /dev/sda1 jest podmontowany na /mnt/backup.
# Synchronizacja home na dysk zewnętrzny
rsync -aAXH --delete --info=progress2 /home/ /mnt/backup/home-backup/
# Weryfikacja
du -sh /mnt/backup/home-backup/
ls -la /mnt/backup/home-backup/
# Sprawdzenie rzeczywistych rozmiarów LV przed resize
sudo lvs --units g vg0
Na podstawie wyniku lvs obliczamy docelowy rozmiar home:
home_target = 446.11 − 65 (root) − 65 (root-backup) − swap_actual Przy swap=32G: home_target = 284G
Resize LVM — Task 1: Live USB
Operacja wykonywana z live ISO Arch Linux. Wymagane narzędzia: cryptsetup, lvm2, e2fsprogs, rsync — wszystkie obecne w standardowym ISO.
Ostrzeżenie
Kolejność kroków jest krytyczna. Uruchomienie lvreduce przed resize2fs nieodwracalnie niszczy dane na wolumenie.
# Otwieramy LUKS i aktywujemy VG
cryptsetup open /dev/nvme0n1p2 cryptroot
vgchange -ay
# Zmniejszamy root: 105G → 65G
e2fsck -f /dev/vg0/root
resize2fs /dev/vg0/root 60G # fs mniejszy niż LV
lvreduce -L 65G /dev/vg0/root
resize2fs /dev/vg0/root # rozciągamy fs do końca LV
e2fsck -f /dev/vg0/root
# Zmniejszamy home: 331G → 284G
e2fsck -f /dev/vg0/home
resize2fs /dev/vg0/home 279G
lvreduce -L 284G /dev/vg0/home
resize2fs /dev/vg0/home
e2fsck -f /dev/vg0/home
# Tworzymy root-backup
lvcreate -L 65G -n root-backup vg0
mkfs.ext4 -L root-backup /dev/vg0/root-backup
# Pierwszy sync root → root-backup
mkdir -p /mnt/root /mnt/root-backup
mount /dev/vg0/root /mnt/root
mount /dev/vg0/root-backup /mnt/root-backup
rsync -aAXH --delete --info=progress2 \
--exclude=/proc --exclude=/sys --exclude=/dev --exclude=/run \
--exclude=/tmp --exclude=/boot --exclude=/home \
--exclude=/mnt --exclude=/lost+found \
/mnt/root/ /mnt/root-backup/
# Aktualizacja fstab w backupie
ROOT_UUID=$(blkid -s UUID -o value /dev/vg0/root)
BACKUP_UUID=$(blkid -s UUID -o value /dev/vg0/root-backup)
sed -i "s/$ROOT_UUID/$BACKUP_UUID/" /mnt/root-backup/etc/fstab
# Zamknięcie i restart
umount /mnt/root /mnt/root-backup
vgchange -an vg0
cryptsetup close cryptroot
reboot
Po restarcie do normalnego systemu dodajemy wpis bootloadera (Task 9).
Skrypt mark-root-backup-pending — Task 2
Plik: /usr/local/bin/mark-root-backup-pending
Uruchamiany automatycznie przez pacman hook po każdej transakcji. Stawia flagę informującą że backup jest nieaktualny.
#!/usr/bin/env bash
set -euo pipefail
DIR=/var/lib/sync-root-backup
FLAG="$DIR/pending"
mkdir -p "$DIR"
chmod 755 "$DIR"
date '+%Y-%m-%d %H:%M:%S' > "$FLAG"
chmod 644 "$FLAG"
Plik flagi jest własnością root:root ale czytelny dla wszystkich (tryb 644), dzięki czemu skrypty waybara i funkcja w powłoce mogą go odczytać bez uprawnień administratora.
Skrypt sync-root-backup — Task 3
Plik: /usr/local/bin/sync-root-backup
Główny skrypt synchronizacji root → root-backup. Uruchamiany ręcznie (sudo sync-root-backup) lub przez kliknięcie ikony w waybarze (pkexec).
#!/usr/bin/env bash
set -euo pipefail
BACKUP_DEV=/dev/vg0/root-backup
MOUNT_POINT=/mnt/root-backup
FLAG=/var/lib/sync-root-backup/pending
LOG_TAG=sync-root-backup
log() { logger -t "$LOG_TAG" "$*"; echo "$*"; }
if [[ ! -b "$BACKUP_DEV" ]]; then
log "Błąd: $BACKUP_DEV nie istnieje. Czy wykonano resize LVM?"
exit 1
fi
if mountpoint -q "$MOUNT_POINT"; then
log "Błąd: $MOUNT_POINT jest już podmontowany."
exit 1
fi
mkdir -p "$MOUNT_POINT"
mount "$BACKUP_DEV" "$MOUNT_POINT"
log "Zamontowano $BACKUP_DEV na $MOUNT_POINT"
START=$(date +%s)
rsync -aAXH --delete \
--exclude=/proc \
--exclude=/sys \
--exclude=/dev \
--exclude=/run \
--exclude=/tmp \
--exclude=/boot \
--exclude=/home \
--exclude=/mnt \
--exclude=/lost+found \
--exclude=/var/lib/sync-root-backup \
--info=progress2 \
/ "$MOUNT_POINT"/
ROOT_UUID=$(blkid -s UUID -o value /dev/vg0/root)
BACKUP_UUID=$(blkid -s UUID -o value "$BACKUP_DEV")
sed -i "s/$ROOT_UUID/$BACKUP_UUID/" "$MOUNT_POINT/etc/fstab"
log "Zaktualizowano fstab: $ROOT_UUID → $BACKUP_UUID"
rm -f "$FLAG"
umount "$MOUNT_POINT"
ELAPSED=$(( $(date +%s) - START ))
log "Sync zakończony w ${ELAPSED}s."
Katalog /var/lib/sync-root-backup jest wykluczony z rsync — stan flagi jest niezależny na każdej partycji. Dzięki temu po zabootowaniu z root-backup nie pojawia się fałszywy alarm o niezsynchronizowanym backupie.
Logi trafiają do systemd journal pod tagiem sync-root-backup:
journalctl -t sync-root-backup
Przypis
Przy błędzie rsync flaga set -e przerwie skrypt bez wykonania umount, pozostawiając /mnt/root-backup podmontowany. Przy kolejnym uruchomieniu skrypt wyjdzie z błędem na guardzie mountpoint -q. W takim przypadku należy ręcznie wykonać sudo umount /mnt/root-backup.
Skrypt restore-root-from-backup
Plik: /usr/local/bin/restore-root-from-backup
Skrypt odwrotny do sync-root-backup — kopiuje root-backup → root w celu wycofania problematycznej aktualizacji. Uruchamiany wyłącznie po zabootowaniu z partycji root-backup.
#!/usr/bin/env bash
set -euo pipefail
ROOT_DEV=/dev/vg0/root
BACKUP_DEV=/dev/vg0/root-backup
MOUNT_POINT=/mnt/root-restore
FLAG=/var/lib/sync-root-backup/pending
LOG_TAG=restore-root
log() { logger -t "$LOG_TAG" "$*"; echo "$*"; }
LIVE_DEV=$(findmnt -n -o SOURCE /)
if [[ "$LIVE_DEV" != "$BACKUP_DEV" ]]; then
log "Błąd: Nie uruchomiono z partycji root-backup (aktywna: $LIVE_DEV)."
log "Ten skrypt uruchamiaj wyłącznie po zabootowaniu z 'Arch Linux (backup)'."
exit 1
fi
if [[ ! -b "$ROOT_DEV" ]]; then
log "Błąd: $ROOT_DEV nie istnieje."
exit 1
fi
if mountpoint -q "$MOUNT_POINT"; then
log "Błąd: $MOUNT_POINT jest już podmontowany."
exit 1
fi
mkdir -p "$MOUNT_POINT"
mount "$ROOT_DEV" "$MOUNT_POINT"
log "Zamontowano $ROOT_DEV na $MOUNT_POINT"
START=$(date +%s)
rsync -aAXH --delete \
--exclude=/proc \
--exclude=/sys \
--exclude=/dev \
--exclude=/run \
--exclude=/tmp \
--exclude=/boot \
--exclude=/home \
--exclude=/mnt \
--exclude=/lost+found \
--exclude=/var/lib/sync-root-backup \
--info=progress2 \
/ "$MOUNT_POINT"/
BACKUP_UUID=$(blkid -s UUID -o value "$BACKUP_DEV")
ROOT_UUID=$(blkid -s UUID -o value "$ROOT_DEV")
sed -i "s/$BACKUP_UUID/$ROOT_UUID/" "$MOUNT_POINT/etc/fstab"
log "Zaktualizowano fstab: $BACKUP_UUID → $ROOT_UUID"
rm -f "$MOUNT_POINT$FLAG"
umount "$MOUNT_POINT"
ELAPSED=$(( $(date +%s) - START ))
log "Przywracanie zakończone w ${ELAPSED}s. Uruchom ponownie i zabootuj z 'Arch Linux'."
Guard clause na początku weryfikuje aktywną partycję przez findmnt — uruchomienie ze zwykłego root skończy się błędem i wyjściem przed jakąkolwiek operacją. Logi dostępne przez:
journalctl -t restore-root
Pacman hook — Task 4
Plik: /etc/pacman.d/hooks/99-sync-root-backup.hook
Hook uruchamia mark-root-backup-pending po każdej udanej transakcji pacmana. Działa również z yay i innymi AUR helperami — hooki są wyzwalane przez bibliotekę libalpm, nie przez interfejs CLI.
[Trigger]
Operation = Install
Operation = Upgrade
Operation = Remove
Type = Package
Target = *
[Action]
Description = Oznaczanie backupu root jako nieaktualny...
When = PostTransaction
Exec = /usr/local/bin/mark-root-backup-pending
Prompt w terminalu — Task 5
Plik: ~/.zsh_<USER> (sourcowany z ~/.zshrc)
Funkcja dodana na końcu pliku. Przy każdym otwarciu terminala sprawdza aktywną partycję i stan flagi, po czym wypisuje stosowne przypomnienie:
# A/B root backup reminder
_sync_root_check() {
local live_dev
live_dev=$(findmnt -n -o SOURCE / 2>/dev/null)
if [[ "$live_dev" == "/dev/vg0/root-backup" ]]; then
echo "[!] Uruchomiono z partycji root-backup. Uruchom: sudo restore-root-from-backup"
return
fi
local flag="/var/lib/sync-root-backup/pending"
[[ -f "$flag" ]] || return
local ts
ts=$(cat "$flag")
echo "[!] Backup root niezsynchronizowany od $ts. Uruchom: sudo sync-root-backup"
}
_sync_root_check
Przykładowe wyjście na partycji root po aktualizacji:
[!] Backup root niezsynchronizowany od 2026-04-30 14:22:15. Uruchom: sudo sync-root-backup
Przykładowe wyjście po zabootowaniu z root-backup:
[!] Uruchomiono z partycji root-backup. Uruchom: sudo restore-root-from-backup
Waybar — skrypty — Task 6
Dwa skrypty obsługujące moduł waybara. Oba rozróżniają aktywną partycję przez findmnt i dostosowują komunikat do kontekstu.
Skrypt statusu
Plik: ~/.config/waybar/scripts/sync-backup-status.sh
Odpytywany co 30 sekund. Zwraca JSON dla waybara.
#!/usr/bin/env bash
LIVE_DEV=$(findmnt -n -o SOURCE /)
FLAG=/var/lib/sync-root-backup/pending
if [[ "$LIVE_DEV" == "/dev/vg0/root-backup" ]]; then
printf '{"text":"⚠ BACKUP","tooltip":"Uruchomiono z root-backup. Kliknij aby przywrócić root.","class":"on-backup"}\n'
exit 0
fi
if [[ ! -f "$FLAG" ]]; then
printf '{"text":"","tooltip":"","class":"hidden"}\n'
exit 0
fi
TS=$(cat "$FLAG")
printf '{"text":"⚠","tooltip":"Backup root niezsynchronizowany od %s","class":"pending"}\n' "$TS"
Skrypt kliknięcia
Plik: ~/.config/waybar/scripts/sync-backup-click.sh
Uruchamiany po kliknięciu ikony. Wykrywa aktywną partycję i oferuje odpowiednią operację: synchronizację (na root) lub przywrócenie (na root-backup).
#!/usr/bin/env bash
LIVE_DEV=$(findmnt -n -o SOURCE /)
if [[ "$LIVE_DEV" == "/dev/vg0/root-backup" ]]; then
zenity --question \
--title="Przywracanie root" \
--text="Uruchomiono z partycji root-backup.\nSkopiować root-backup → root i przywrócić system?" \
--ok-label="Przywróć" \
--cancel-label="Anuluj" || exit 0
pkexec /usr/local/bin/restore-root-from-backup \
&& zenity --info \
--title="Przywracanie root" \
--text="Przywracanie zakończone.\nUruchom ponownie i zabootuj z 'Arch Linux'." \
|| zenity --error \
--title="Przywracanie root" \
--text="Przywracanie nie powiodło się.\nSprawdź: journalctl -t restore-root"
exit 0
fi
FLAG=/var/lib/sync-root-backup/pending
[[ -f "$FLAG" ]] || exit 0
zenity --question \
--title="Backup root" \
--text="Backup root jest nieaktualny.\nSynchronizować teraz?" \
--ok-label="Synchronizuj" \
--cancel-label="Anuluj" || exit 0
pkexec /usr/local/bin/sync-root-backup \
&& zenity --info \
--title="Backup root" \
--text="Synchronizacja zakończona pomyślnie." \
|| zenity --error \
--title="Backup root" \
--text="Synchronizacja nie powiodła się.\nSprawdź: journalctl -t sync-root-backup"
Polkit i sudoers — Task 7
Dwa mechanizmy autoryzacji umożliwiające uruchomienie skryptów bez hasła — zarówno przez pkexec (waybar) jak i sudo (terminal).
Reguła polkit
Plik: /etc/polkit-1/rules.d/50-sync-root-backup.rules
Pozwala użytkownikom grupy wheel uruchamiać oba skrypty przez pkexec bez okna hasła:
polkit.addRule(function(action, subject) {
var allowed = [
"/usr/local/bin/sync-root-backup",
"/usr/local/bin/restore-root-from-backup"
];
if (action.id === "org.freedesktop.policykit.exec" &&
allowed.indexOf(action.lookup("program")) !== -1 &&
subject.isInGroup("wheel")) {
return polkit.Result.YES;
}
});
Wpis sudoers
Plik: /etc/sudoers.d/sync-root-backup
Umożliwia ręczne wywołanie obu skryptów przez sudo bez podawania hasła:
<USER> ALL=(root) NOPASSWD: /usr/local/bin/sync-root-backup, /usr/local/bin/restore-root-from-backup
Waybar — konfiguracja i CSS — Task 8
Zmiany w konfiguracji waybara.
Moduł w ~/.config/waybar/config
Dodanie "custom/sync-backup" do modules-right (przed "clock") oraz definicja modułu:
"custom/sync-backup": {
"exec": "~/.config/waybar/scripts/sync-backup-status.sh",
"interval": 30,
"return-type": "json",
"on-click": "~/.config/waybar/scripts/sync-backup-click.sh"
}
Style CSS w ~/.config/waybar/style.css
Trzy klasy: hidden (brak ikony), pending (migająca czerwona po aktualizacji), on-backup (pomarańczowa po zabootowaniu z backupu). Animacja używa nazwy sync-blink — plik zawiera już @keyframes blink dla baterii i nazwy nie mogą kolidować.
#custom-sync-backup {
padding: 0 5px;
color: #ffffff;
}
#custom-sync-backup.hidden {
opacity: 0;
min-width: 0;
padding: 0;
}
@keyframes sync-blink {
50% { opacity: 0.15; }
}
#custom-sync-backup.pending {
color: #ff4444;
animation-name: sync-blink;
animation-duration: 1s;
animation-timing-function: steps(2);
animation-iteration-count: infinite;
animation-direction: alternate;
}
#custom-sync-backup.on-backup {
color: #ffaa00;
}
Po modyfikacji przeładuj waybar:
pkill waybar && swaymsg exec waybar
Wpis systemd-boot — Task 9
Plik: /boot/loader/entries/arch-backup.conf
Kopia aktywnego wpisu z dwiema zmianami — title i root=. UUID kontenera LUKS oraz UUID swapu pozostają bez zmian (są wspólne dla obu slotów):
title Arch Linux (backup)
linux /vmlinuz-linux
initrd /intel-ucode.img
initrd /initramfs-linux.img
options rd.luks.name=f2898094-ad76-47cc-a637-61d629a01021=cryptroot \
root=/dev/vg0/root-backup rw \
resume=UUID=fb45ad19-0717-4259-bf82-ab132e2c031b \
rw quiet splash loglevel=3 \
modprobe.blacklist=nouveau nouveau.modeset=0
Przypis
root= używa ścieżki urządzenia /dev/vg0/root-backup, nie UUID — zgodnie z oryginalnym wpisem arch.conf. LVM mapuje tę ścieżkę dynamicznie po odszyfrowaniu LUKS.
Diagnostyka i rekalibracja baterii — Task 10
Bateria MacBook Pro 11,3: aftermarket (SMP / bq20z451), wymieniona 2022, specyfikacja: 11.26 V / 8800 mAh.
Zmierzone parametry (2026-04-30)
| Parametr | Wartość |
|---|---|
| charge_full | 4480 mAh |
| charge_full_design | 8600 mAh |
| capacity | 52% |
| cycle_count | 364 |
| voltage_now | 12.668 V (pełne naładowanie) |
Interpretacja
Pojemność 52% przy zaledwie 364 cyklach to anomalia. Bateria w tym wieku powinna zachować ~85–90% pojemności. Chip bq20z451 (Texas Instruments, algorytm Impedance Track) jest podatny na utratę kalibracji po głębokim rozładowaniu lub przy niezgodności parametrów ogniw. Objawia się to zaniżonym raportowaniem pojemności i przedwczesnym odcinaniem zasilania pod obciążeniem — mimo że ogniwa mają jeszcze energię.
Komendy diagnostyczne
upower -i $(upower -e | grep -i bat)
sudo tlp-stat -b
cat /sys/class/power_supply/BAT0/cycle_count
cat /sys/class/power_supply/BAT0/capacity
Procedura rekalibracji BMS
Wykonaj trzy pełne cykle rozładowania i ładowania:
- Podłącz zasilacz, naładuj do 100% (poczekaj na state: fully-charged).
- Odłącz zasilacz; używaj laptopa normalnie do całkowitego wyłączenia z powodu rozładowania — nie wymuszaj wyłączenia ręcznie.
- Odczekaj 30 minut.
- Naładuj do 100% bez przerywania ładowania.
- Powtórz kroki 1–4 jeszcze dwa razy (łącznie 3 cykle).
- Sprawdź capacity przez sudo tlp-stat -b.
Interpretacja wyników rekalibracji
| Wynik | Decyzja |
|---|---|
| capacity wzrosło do > 75% | Rekalibracja pomogła — użytkuj dalej |
| capacity nadal < 60% | Ogniwa degradowane — wymiana uzasadniona |
| Nagłe wyłączenia ustały | BMS był skalibrowany błędnie — OK |
| Nagłe wyłączenia nadal przy > 20% SoC | Wymiana uzasadniona |
Kolejność wykonania
Task 0 → Task 1 → Task 2 → Task 3 → Task 4
↓
Task 9 ← Task 8 ← Task 7 ← Task 6 ← Task 5
Task 10 — niezależny, prowadzony równolegle
Tasks 2–9 wykonane przez agenta (oprogramowanie gotowe). Tasks 0, 1, 10 wykonuje użytkownik ręcznie. Tasks 2–9 staną się w pełni funkcjonalne dopiero po ukończeniu Task 1 (wolumen vg0/root-backup musi istnieć).
Pliki projektu
| Plik | Opis |
|---|---|
| /usr/local/bin/mark-root-backup-pending | Stawia flagę po transakcji pacmana |
| /usr/local/bin/sync-root-backup | Synchronizuje root → root-backup |
| /usr/local/bin/restore-root-from-backup | Przywraca root ← root-backup (uruchamiać z partycji backup) |
| /etc/pacman.d/hooks/99-sync-root-backup.hook | Wyzwala mark po każdej transakcji |
| ~/.zsh_<USER> | Prompt z przypomnieniem — rozróżnia partycję root i root-backup |
| ~/.config/waybar/scripts/sync-backup-status.sh | Status JSON dla waybara (3 stany: hidden / pending / on-backup) |
| ~/.config/waybar/scripts/sync-backup-click.sh | Obsługa kliknięcia (sync lub restore w zależności od partycji) |
| /etc/polkit-1/rules.d/50-sync-root-backup.rules | Autoryzacja pkexec bez hasła dla obu skryptów (wheel) |
| /etc/sudoers.d/sync-root-backup | NOPASSWD dla sudo sync-root-backup i restore-root-from-backup |
| ~/.config/waybar/config | Definicja modułu custom/sync-backup |
| ~/.config/waybar/style.css | CSS z animacją sync-blink i klasą on-backup |
| /boot/loader/entries/arch-backup.conf | Wpis bootloadera dla backup root |