Czy można użyć Raspberry Pi do utworzenia własnej kopii zapasowej?


78

To pytanie odpowiada na pytanie, w jaki sposób używam komputera zewnętrznego do utworzenia kopii zapasowej mojego RPi.

Zastanawiam się, czy mogę utworzyć kopię zapasową aktualnie używanej karty SD i skopiować ją do pliku na urządzeniu pamięci USB. czy to możliwe? Jeśli nie, to czy istnieje sposób na utworzenie kopii zapasowej RPi bez angażowania innego komputera?


2
Jasne, ale pomiń / tmp, / run, / proc, / sys, / dev i / mnt. Nie musisz tworzyć obrazu, potrzebujesz kopii zapasowej, z której możesz utworzyć lub zaktualizować obraz. Więc nie używaj dd, spójrz rsync.
złotowłosa

1
@Goldilocks Chciałbym, aby ten komentarz zawierał pełniejszą odpowiedź wyjaśniającą proces tworzenia kopii zapasowych i przywracania, o którym myślisz.
Eric Wilson

Zrobione - przykro mi zajęło mi kilka dni, aby znaleźć czas.
złotowłosy

1
Jeśli wolumin docelowy jest wystarczająco duży, ponowne zamontowanie systemu plików tylko do odczytu i wykonanie ddkopii o odpowiednim rozmiarze bloku prawdopodobnie będzie najszybsze w przypadku „nowej” kopii. Robienie kopii plik po pliku na nośniku flash / SD jest prawdopodobnie złym pomysłem.
Chris Stratton,

Odpowiedzi:


86

Oto wprowadzenie do korzystania rsyncz kopii zapasowej na Pi. Po utworzeniu początkowej kopii zapasowej utrzymanie jej w ten sposób jest znacznie szybsze niż ciągłe zgrywanie całego obrazu. Możesz to zrobić na lokalnym dysku twardym lub w sieci.

W rzeczywistości nie potrzebujesz pełnej kopii działającego systemu jako kopii zapasowej, ponieważ niektóre rzeczy rzekomo w systemie plików istnieją tylko w czasie wykonywania. Dołączenie tego do kopii zapasowej, a następnie użycie go do odtworzenia obrazu później może spowodować problemy.

Są też inne wyjątki. rsyncmoże zaakceptować listę ( globalnych ) wzorców do wykluczenia, które można odczytać z pliku, więc najpierw przejrzyjmy, co powinno być w takim pliku. Pamiętaj, że wpisy mają formę, /directory/*a nie formę /directory. Jest tak, ponieważ chcemy, aby istniały, ale nie chcemy niczego w nich kopiować.

/proc/*
/sys/*

Te tak naprawdę nie istnieją na dysku. Są interfejsem do jądra, które tworzy je i utrzymuje w pamięci . Jeśli skopiujesz je, a następnie skopiujesz z powrotem do systemu i uruchomisz, będzie to (co najwyżej) bez znaczenia, ponieważ jądro używa ich jako punktów montowania dla interfejsów [Jeśli chcesz zobaczyć, co się stanie po zamontowaniu partycji systemu plików w katalogu z danymi, spróbuj. Działa i nie wyrządzi żadnej szkody, ale rzeczy, które były w katalogu, są teraz niedostępne.]

Należy pamiętać, że ważne jest, że /sysi /procpunkty montowania istnieje. Ale nic nie powinny zawierać. Kolejny:

/dev/*

devKatalog nie jest całkiem tak samo jak proci sysale dla naszych celów jest. Jeśli uważasz, że powinieneś to zapisać, aby mieć te same węzły urządzenia w kopii zapasowej lub coś w tym rodzaju, jesteś w błędzie . Nie zawracaj sobie głowy Nie kopiuj dev. Dawno, dawno temu Linux działał w ten sposób, ale już nie.

/boot/*

Jest to rodzaj szczególnego przypadku z większością (być może wszystkimi) specyficznych dystrybucji Pi, takich jak Raspbian. W rzeczywistości jest to punkt montowania pierwszej partycji vfat. Zajmiemy się tym osobno. Cokolwiek robisz, nie zawracaj sobie głowy włączaniem go tutaj, ponieważ znowu jest to punkt montowania.

/tmp/*
/run/*

/runna ogół też nie jest na dysku, jest w pamięci. Być może /tmpmoże być też (zaoszczędziłoby to trochę akcji karty SD), ale w każdym razie, jak sugerują nazwy, nie są to miejsca do przechowywania trwałych danych. Aplikacje, które ich używają, oczekują, że mogą zostać usunięte przy każdym uruchomieniu.

/mnt/*
/media/*

Są to szczególnie ważne, jeśli planujesz wykonać kopię zapasową na dysku twardym lub w pamięci USB, a urządzenie jest w /mntlub /media(automatyczne montowanie ma tendencję do korzystania z tego drugiego), ponieważ jeśli nie wykluczysz położenia tych urządzeń w systemie plików, utwórz pętlę, tworząc kopię zapasową zawartości dysku, aż zabraknie miejsca. Myślę, że rsync może być wystarczająco mądry, aby dostrzec coś głupiego, ale staraj się unikać testowania przesłanki.

Przejdź do faktycznego tworzenia kopii zapasowych: Utwórz katalog, na którym chcesz utworzyć kopię zapasową na lokalnie zamontowanym dysku twardym, urządzeniu USB itp. - np. „Pi_backup”. Możesz na przemian tworzyć kopie zapasowe w zdalnej lokalizacji za pośrednictwem ssh(patrz poniżej) lub przy użyciu sieciowego systemu plików, ale prawdopodobnie zajmie to trochę czasu po raz pierwszy.

Jeśli plik zawierający listę do wykluczenia to /rsync-exclude.txt1, a dysk to /mnt/usbhd, wykonaj kopię zapasową:

rsync -aHv --delete --exclude-from=/rsync-exclude.txt / /mnt/usbhd/pi_backup/

Zauważ, że na końcu jest ukośnikpi_backup/ .

To zajmie trochę czasu i wygeneruje dużo danych wyjściowych (jeśli chcesz to sprawdzić w dzienniku, dołącz > rsync.log). --deleteza pierwszym razem jest bez znaczenia, ale do aktualizowania kopii zapasowej używaj jej. To gwarantuje, że rzeczy, które później usunąłeś z Pi, również zostaną usunięte z kopii zapasowej. aZestawy rekurencji do katalogów i sprawia, że wszystkie atrybuty plików mecz. -Hjest zachowanie twardych linków 2 , vjest dla pełnych, dlatego dostajesz trochę danych wyjściowych (w przeciwnym razie rsyncjest cicho). Zobacz man rsyncwięcej.

Istnieje skrót, dzięki któremu można pominąć --exclude-fromplik. Jeśli masz pewność, że wszystkie rzeczy, których nie chcesz kopiować ( /tmpitp.), Znajdują się w osobnych systemach plików, możesz po prostu użyć:

rsync -axHv --delete-during / /mnt/usbhd/pi_backup/

-xzostał wstawiony. Jest to krótka forma --one-file-system, która mówi, rsyncaby nie przekraczać granic systemu plików. Osobiście wolę --exclude-from, ale na przykład domyślny Raspbian, --one-file-systembędzie działał dobrze. Możesz użyć obu, jeśli chcesz -xzachować ostrożność: D

To nie jest kompletna kopia zapasowa. Wystarczy, jeśli nic nie włożyłeś booti nie masz nic przeciwko użyciu kopii zapasowej do przywrócenia systemu poprzez włożenie karty do komputera i uruchomienie:

rsync -av --delete-during /mnt/usbhd/pi_backup/ /mnt/sdcard_partition2/

Możesz to również zrobić z kartą z nowym obrazem (zakładając, że jest taki sam jak obraz podstawowy), chociaż jest to trochę nieefektywne, jeśli musisz utworzyć obraz (ponieważ następnie zamierzasz go zastąpić). Możesz także podłączyć inną kartę SD za pomocą adaptera USB z takim obrazem i użyć powyższej metody, aby zachować duplikat karty.

Jeśli wstawiłeś coś /boot(np. Niestandardowe jądro), w tym także /boot/config.txtchcesz to zrobić (dość proste - nie ma w tym wiele). Po prostu zrób to osobno, a po przywróceniu pliki zostaną przeniesione na pierwszą partycję.

Zobacz tutaj, jeśli chcesz utworzyć pusty obraz w stylu Raspbian, który możesz następnie utworzyć kopię zapasową. Możesz użyć podobnej metodologii, aby stworzyć pustą kartę w stylu Raspbian - zamiast zajmować się .imgplikiem, będziesz miał do czynienia z prawdziwym urządzeniem (np. /dev/sdb), Co oznacza, że ​​musisz tylko utworzyć tablicę partycji, fdiska następnie format /dev/sdb1i sdb2(lub cokolwiek) z mkfs.

Ale kopiowanie całego obrazu jest łatwiejsze! Po co zawracać sobie tym głowę?

To nie jest takie trudne; Wróciłem do pustej karty (sformatowanej zgodnie z ostatnim linkiem) w 10 minut. Tak, samo użycie ddcałości jest prostsze (jeśli znajdziesz takie rzeczy, jak słowa mylące ...), ALE to zajmuje trochę czasu za każdym razem, gdy chcesz zaktualizować kopię zapasową, ponieważ musisz zrobić 100% za każdym razem. Używanie rsync, po utworzeniu kopii zapasowej, jej aktualizowanie jest znacznie szybsze, dzięki czemu można tak skonfigurować, aby codziennie odbywała się bezboleśnie za pośrednictwem crona. Nawet przez sieć. Co sześć godzin. Im częściej to robisz, tym mniej czasu to zajmie.

rsync przez ssh

Oto przykład:

rsync [options] --rsh="ssh [ssh options]" root@[the pi ip]:/ /backup/rpi/

„Opcje” to np. -av --delete --exclude-from=/rsync-exclude.txtA „opcje ssh” to to, czego normalnie używasz (jeśli cokolwiek). Musisz mieć dostęp do roota poprzez sshto zrobić dla celów kopii zapasowej systemu (ustawiony PermitRootLogin=yesw /etc/ssh/sshd_configi zrestartuj serwer).


1 Powinieneś zachować ten plik. Możesz umieszczać w nim komentarze w wierszach rozpoczynających się od #lub ;. Może to obejmować rzeczywiste rsyncpolecenie, które można później skopiować i wkleić, abyś nie musiał pamiętać go za każdym razem.

2 Dzięki Kris za wskazanie rsyncnie robi tego automatycznie.


Złotowłosa. To wygląda na świetne wykorzystanie rysync. Czy jest jakaś szansa, aby zamienić go w skrypt?
totalitarny

Zamiast ręcznie wykluczać wszystkie punkty montowania, dlaczego nie mkdir /tmp/backupable && mount --bind / /tmp/backupablei zsynchronizować to? Ma to również tę zaletę, że tworzy kopie zapasowe danych przechowywanych w miejscach „zasłoniętych” przez coś tam zamontowanego.
n.

@ n.st Dobry pomysł (lol)! Zredagowałem sugestię w pytaniu, chociaż nadal uważam, że używanie --exclude-fromjest lepszym pomysłem. Jeśli masz czas, możesz napisać to jako osobną odpowiedź, masz mój głos i mogę to odnieść. Ta odpowiedź jest wystarczająco długa.
złotowłosy

1
@IgorGanapolsky Intencją jest, aby nie tworzyć obrazu (przeczytaj część „Ale kopiowanie całego obrazu jest łatwiejsze! Po co zawracać sobie tym głowę ?” ). Oprócz tego, że po utworzeniu jest łatwiejsza i szybsza w utrzymaniu, ta metoda jest na ogół bardziej elastyczna. Jeśli chcesz użyć go później, aby utworzyć .img, możesz; to i to powinno pomóc wyjaśnić, w jaki sposób są one zbudowane i jak można je tworzyć.
Złotowłosa

1
Zobacz akapit, który zaczyna się: „To nie do końca pełna kopia zapasowa ...” . Zasadniczo jest to dokładnie to samo na odwrót. Może to pomóc w niektórych koncepcjach, które ludzie są często mylone przez / about.
Złotowłosa

24

Działający skrypt ze społeczności Raspberry wykonany przez członka tam.

Możesz ponownie używać i poprawiać kod, jak tylko chcesz. Jest dobrze udokumentowany i zrozumiały.

#!/bin/bash

# Setting up directories
SUBDIR=raspberrypi_backups
DIR=/hdd/$SUBDIR

echo "Starting RaspberryPI backup process!"

# First check if pv package is installed, if not, install it first
PACKAGESTATUS=`dpkg -s pv | grep Status`;

if [[ $PACKAGESTATUS == S* ]]
   then
      echo "Package 'pv' is installed."
   else
      echo "Package 'pv' is NOT installed."
      echo "Installing package 'pv'. Please wait..."
      apt-get -y install pv
fi

# Check if backup directory exists
if [ ! -d "$DIR" ];
   then
      echo "Backup directory $DIR doesn't exist, creating it now!"
      mkdir $DIR
fi

# Create a filename with datestamp for our current backup (without .img suffix)
OFILE="$DIR/backup_$(date +%Y%m%d_%H%M%S)"

# Create final filename, with suffix
OFILEFINAL=$OFILE.img

# First sync disks
sync; sync

# Shut down some services before starting backup process
echo "Stopping some services before backup."
service apache2 stop
service mysql stop
service cron stop

# Begin the backup process, should take about 1 hour from 8Gb SD card to HDD
echo "Backing up SD card to USB HDD."
echo "This will take some time depending on your SD card size and read performance. Please wait..."
SDSIZE=`blockdev --getsize64 /dev/mmcblk0`;
pv -tpreb /dev/mmcblk0 -s $SDSIZE | dd of=$OFILE bs=1M conv=sync,noerror iflag=fullblock

# Wait for DD to finish and catch result
RESULT=$?

# Start services again that where shutdown before backup process
echo "Start the stopped services again."
service apache2 start
service mysql start
service cron start

# If command has completed successfully, delete previous backups and exit
if [ $RESULT = 0 ];
   then
      echo "Successful backup, previous backup files will be deleted."
      rm -f $DIR/backup_*.tar.gz
      mv $OFILE $OFILEFINAL
      echo "Backup is being tarred. Please wait..."
      tar zcf $OFILEFINAL.tar.gz $OFILEFINAL
      rm -rf $OFILEFINAL
      echo "RaspberryPI backup process completed! FILE: $OFILEFINAL.tar.gz"
      exit 0
# Else remove attempted backup file
   else
      echo "Backup failed! Previous backup files untouched."
      echo "Please check there is sufficient space on the HDD."
      rm -f $OFILE
      echo "RaspberryPI backup process failed!"
      exit 1
fi

Zastanów się nad dodaniem komentarzy do oryginalnego forum lub opublikuj własną wersję, aby pomóc w dojrzewaniu treści. Daj trochę, daj trochę.

* I dziękuję za oddanie AndersW (kliknij, aby uzyskać skrypt GIT)


2
Co się stanie, jeśli system plików (usuwanie plików, dodawanie nowych plików) zmieni się w czasie podczas tworzenia kopii zapasowej pi?
keiki

2
Tworzę kopie zapasowe kilku dysków, gdy są one uruchomione przy użyciu rsync, i często byłem w stanie uzyskać dokładnie to, czego potrzebuję z tych kopii zapasowych plików. Jednak ogólnie rzecz biorąc, uniksowy system plików nie może być idealnie skopiowany (z każdym bitem na miejscu i poprawnym), gdy system plików jest zamontowany (*). Kopia wykonana podczas montowania systemu jest czasami nazywana „brudną kopią”. Można podjąć szereg działań w celu poprawy jakości brudnej kopii (jak w powyższym skrypcie, wyłączając crona i mysql), ale nie może być doskonały. Twoje zdrowie! * - Mylę się co do tego, zależy to od systemu plików.
Tai Viinikka

1
Możesz spojrzeć na zalecane narzędzia do tworzenia kopii zapasowych Debiana i sprawdzić, czy Pi ma ich port. rsnapshotbrzmi obiecująco
Piotr Kula

1
@TaiViinikka Nie potrzebujesz idealnej kopii. Potrzebujesz częściowej kopii, którą można (szybko i łatwo) ponownie nałożyć na oryginalny obraz podstawowy. rsyncjest droga; kiedy jutro będę miał czas, dodam odpowiedź. rsnapshotwarto również zbadać.
złotowłosa

3
Na podstawie powyższej odpowiedzi ppumkins zsynchronizowałem skrypt „dd” z najnowszymi komentarzami w oryginalnym wątku i sam dodałem kilka drobnych usprawnień. Wynik końcowy jest dostępny tutaj: < github.com/aweijnitz/pi_backup >. Nie wahaj się dodawać ulepszeń i wysyłać mi żądania ściągania.
AndersW

14

Dostosowałem odpowiedź @goldilocks na rsync do tworzenia kopii zapasowych na pi. Wykonuję kopię zapasową na ext4partycję na dysku twardym zamontowanym na Pi. Jeśli dysk twardy nie zostanie podłączony, program rsync skopiuje go do katalogu montowania (do momentu zapełnienia karty SD). Jeśli dysk twardy nie jest zamontowany w rwtrybie, generowane są liczne komunikaty o błędach. Żadne z nich nie jest pożądane, więc sprawdzam, czy moja partycja jest zamontowana w rwtrybie przed kontynuowaniem.

UWAGA 2015-03-03 Zmodyfikowałem swoją odpowiedź, aby dokładnie skopiować twarde linki. Oryginał działał, ale przekształcił wiele dowiązań twardych w pliki. Oprócz marnowania miejsca, zagraża to wielu zastosowaniom, które zakładają, że istnieją twarde linki. (Mój obecny obraz ma 869 linków, wiele w samym Raspbian.)

Mój skrypt, aby to zrobić, jest następujący. (Moja partycja jest PiDatazamontowana/mnt/PiData

#!/bin/bash
# script to synchronise Pi files to backup
BACKUP_MOUNTED=$(mount | awk '/PiData/ {print $6}' | grep "rw")
if [ $BACKUP_MOUNTED ]; then
    echo $BACKUP_MOUNTED
    echo "Commencing Backup"
    rsync -avH --delete-during --delete-excluded --exclude-from=/usr/bin/rsync-exclude.txt / /mnt/PiData/PiBackup/
else
    echo "Backup drive not available or not writable"
fi

Przywróć (lub zaktualizuj inne Pi) za pomocą:

sudo rsync -avH /mnt/PiData/PiBackup/ /

Ulepszyłem, rsync-exclude.txtaby wyeliminować niepotrzebne pliki.

Pierwsza grupa to katalogi udokumentowane przez @goldilocks https://raspberrypi.stackexchange.com/users/5538/

Druga grupa to pliki i katalogi utworzone przez OS X, kiedy uzyskuję dostęp do mojego Pi przy użyciu AFP (Apple Filing Protocol). (Zwykle są one niewidoczne w systemie OS X, ale nie w systemie Raspbian. W każdym razie nie ma potrzeby wykonywania kopii zapasowej.) Nawet jeśli nigdy nie użyjesz AFP, nie spowoduje to żadnych szkód.

Trzecia grupa to pliki, których nie trzeba tworzyć kopii zapasowej (a na pewno nie kopiować do innego Pi). Przykłady fake-hwclock.data, raporty RPi-Monitor. Prawdopodobnie będziesz mieć inne.

/proc/*
/sys/*
/dev/*
/boot/*
/tmp/*
/run/*
/mnt/*

.Trashes
._.Trashes
.fseventsd
.Spotlight-V100
.DS_Store
.AppleDesktop
.AppleDB
Network Trash Folder
Temporary Items

.bash_history
/etc/fake-hwclock.data
/var/lib/rpimonitor/stat/

1
Czy istnieje sposób, aby plik wyjściowy był plikiem .img ?
IgorGanapolsky

@IgorGanapolsky Cóż, ponieważ wszystkie niezbędne pliki są dostępne (z wyjątkiem plików rozruchowych), jest oczywiście możliwe, ale jeśli chcesz, aby obraz był obrazem. Powinieneś zadać nowe pytanie w nowym poście, a nie komentarze.
Milliways,

@Milliways, dlaczego nie powinniśmy używać „sudo rsync ...”? Czy będą jakieś pliki, których nie można zsynchronizować?
Smilia,

6

Mam trzy Pis uruchomione w mojej lokalnej sieci i muszę je regularnie tworzyć kopie zapasowe za pomocą crona, gdy są uruchomione. Dlatego stworzyłem skrypt, który jest w stanie tworzyć kopie zapasowe dd, tar i rsync oraz je przywracać. Wolę używać rsync do tworzenia kopii zapasowych, ale inni ludzie wolą dd lub tar. Jest już używany przez wiele osób. Mam nadzieję, że przyda się także innym :-) raspibackup - Raspberry tworzy kopie zapasowe samego siebie


1
Nie, przepraszam: proszenie użytkownika o uruchomienie (jako root!) Skryptu pobranego przez HTTP jest nieodpowiedzialny. Przekaż ten skrypt w bezpiecznym kanale.
Clément

1
Nie sądzę, że to nie na temat, a rootowanie lub nieważne. Chodzi o to, że oprogramowanie powinno być dystrybuowane w bezpiecznym kanale, a twoja odpowiedź zachęca do złych praktyk bezpieczeństwa.
Clément

1
To byłby wspaniały krok naprzód, tak :)
Clément

2
Uwaga: dostawa przez HTTPS w żaden sposób nie zwiększa bezpieczeństwa w tym przypadku! Nadal pobierasz i uruchamiasz skrypt z Internetu. Bezpiecznym procesem jest pobranie skryptu (http / https nie ma znaczenia), otwarcie skryptu w edytorze i przeczytanie go od góry do dołu, sprawdzenie go pod kątem dziwności i niepewności. Uruchom go tylko wtedy, gdy jesteś zadowolony. Framp może być hakerem dla każdego z nas, a dostarczenie go przez https sprawiłoby, że uśmiechnąłby się w takim przypadku :) (BTW, to nie jest oskarżenie Framp!)
Julian Knight

2
Zgadzam się z Tobą. Dlatego opisano dwa sposoby instalacji skryptu: 1. Użyj skryptu instalatora 2. Pobierz go ręcznie, sprawdź kod, a następnie zainstaluj ręcznie
frun

3

Oto nasze stabilne narzędzie do takich celów: https://github.com/aktos-io/aktos-dcs-tools

To narzędzie jest napisane do make sshpołączeń make backup-root, make mount-rootz odległych miejsc w pamięci na początku, a potem sesje lokalne są dodawane. Obsługuje więc lokalne kopie zapasowe, bezpośrednie zdalne kopie zapasowe, zdalne kopie zapasowe proxy. Kopie zapasowe są tworzone przyrostowo (przesyłane są tylko różnice), a katalogi kopii zapasowych są autonomiczne (wystarczy wybrać katalog / wersję do przywrócenia, każdy katalog ma pełną kopię zapasową). Oczywiście masz wersje (backup.last-0 to najnowsza wersja). Możesz przerwać proces tworzenia kopii zapasowej w dowolnym momencie i kontynuować później.

Oto instrukcje dotyczące konkretnego problemu:

 ssh to-your-raspberry
 cd /mnt/usb0/my-rpi-backups
 git clone https://github.com/ceremcem/aktos-dcs-tools backup-tools
 ln -s backup-tools/Makefile .

 ./backup-tools/configure # you do not need to make any settings for local sessions, just save the default 

 # just for the first time
 make set-local-session  # a flag file is created
 make init               # snapshots directory is created

 # anytime you want to back up
 make backup-root        # backup with rsync

EDYTOWAĆ

Teraz dodano nowy cel: możesz utworzyć fizyczną kartę SD z kopii zapasowych za pomocą jednego polecenia:

make create-disk-from-last-backup

Postępuj zgodnie z instrukcjami, utwórz kartę SD, uruchom RaspberryPi za pomocą nowo utworzonej karty SD.


1

Oto zupełnie inne podejście. Można użyć LVM ( L ogical V POZIOM GŁOŚNOŚCI M anager), aby spójnych kopii zapasowych. Oprócz innych ulepszeń, takich jak łatwe dodawanie, rozszerzanie i zmniejszanie pamięci masowej lub przywracanie systemu operacyjnego do wcześniejszego stanu z migawki, można również tworzyć kopie zapasowe. Nie musisz się martwić dynamicznymi zmianami plików podczas tworzenia kopii zapasowej, ustawianiem systemów plików tylko do odczytu, wykluczaniem określonych katalogów lub czymś innym. Dzięki LVM po prostu tworzysz migawkę, montujesz migawkę i tworzysz kopię zapasową przy użyciu preferowanej metody. Możesz wykonać kopię za pomocą cp -a, zrobić lustro za pomocą rsync, zrobić archiwum za pomocą tarlub zrobić obraz za pomocądd. Zakładając, że masz zamontowane urządzenie kopii zapasowej /mnt/usbhd/pi_backup/, możesz na przykład:

rpi ~$ sudo lvcreate --snapshot --name rpi_snap --size 1G rpi_vg/root_lv
rpi ~$ sudo mkdir /mnt/snapshot
rpi ~$ sudo mount /dev/mapper/rpi_vg-rpi_snap /mnt/snapshot

# make backups
rpi ~$ sudo cp -a /mnt/snapshot/ /mnt/usbhd/pi_backup/
rpi ~$ sudo rsync -aH --delete /mnt/snapshot/ /mnt/usbhd/pi_backup/
rpi ~$ sudo tar -czf /mnt/usbhd/pi_backup/backup.tar.gz -V "Backup of my Raspberry Pi" -C /mnt/snapshot/ ./
rpi ~$ sudo dd if=/mnt/snapshot/ of=/mnt/usbhd/pi_backup/backup.img bs=4M

rpi ~$ sudo umount /mnt/snapshot/
rpi ~$ sudo lvremove rpi_vg/rpi_snap

Konfiguracja LVM zajmuje tylko jeden raz trochę wysiłku . Jak to zrobić, możesz przejrzeć Łatwe kopie zapasowe i migawki działającego systemu z LVM .


0

Znalazłem narzędzie do tworzenia kopii zapasowych, które umożliwia instalowanie obrazów.

Posiada również narzędzia do montowania i zmniejszania obrazów.

Może to być przydatne dla innych

Załączona dokumentacja jest bardzo krótka, dlatego zwracam uwagę na następujące kwestie:

  1. Wyodrębnij narzędzia do dowolnego katalogu i włącz wykonywanie skryptów.
  2. Zamontuj ext4sformatowaną partycję na swoim Pi w /mntlub /media(można użyć dowolnego formatu, który pozwala na duże pliki i jest obsługiwany przez Pi, np. ExFAT lub dysk sieciowy).
  3. Podczas pierwszego uruchomienia pojawi się monit o podanie nazwy obrazu kopii zapasowej, np /mnt/Image/BusterBackup.img
  4. Zostaniesz poproszony o podanie rozmiaru systemu plików ROOT obrazu (w MB), może to być 0 dla najmniejszego możliwego lub puste dla pełnej kopii zapasowej.
  5. Przy kolejnych uruchomieniach wprowadź ścieżkę obrazu kopii zapasowej, aby stopniowo aktualizować.
An example of the commands I used:-
# Mount USB
sudo mount /dev/sda1 /mnt/Image/
# Update backup
sudo image-utils/image-backup /mnt/Image/BusterBackup.img
# Mount backup
sudo image-utils/image-mount /mnt/Image/BusterBackup.img  MountedImages
When done, run:
sudo umount MountedImages; sudo losetup -d /dev/loop0
# Compress backup
sudo sh -c "gzip -9c /mnt/Image/BusterBackup.img  > Images/BusterBackup.img.gz"

Lekko zmodyfikowałem oryginał (aby skopiować punkty montowania), aby poprawnie obliczyć przesunięcia i rozmiary partycji i dodałem kilka komentarzy.

#!/bin/bash
# Original https://raspberrypi.org/forums/viewtopic.php?p=1528736
# 2019-09-26    Modified to set size of boot sector

trap '{ stty sane; echo ""; errexit "Aborted"; }' SIGINT SIGTERM

ADDBLK=0

# Set BOOT_SIZE_MB to the Desired boot sector size (in MB) - should be multiple of 4MB
BOOT_SIZE_MB=256
BOOTSIZEM=$BOOT_SIZE_MB'M'

BOOTBEG=8192
BOOT_SIZE="$((BOOT_SIZE_MB * 1024 * 1024))"
ROUND_SIZE="$((4 * 1024 * 1024))"
# Ensure root sector starts on an Erase Block Boundary (4MB)
ROOTBEG=$(((BOOT_SIZE + ROUND_SIZE -1) / ROUND_SIZE * ROUND_SIZE / 512 + BOOTBEG))

MNTPATH="/tmp/img-backup-mnt"

ONEMB=$((1024 * 1024))

# create BOOT loop device
mkloop1()
{
  local INFO1=""
  local SIZE1=0
  local START1=0

  sync
  INFO1="$(sfdisk -d "${IMGFILE}")"
  START1=$(grep type=c <<< "${INFO1}" | sed -n 's|^.*start=\s\+\([0-9]\+\).*$|\1|p')
  SIZE1=$(grep type=c <<< "${INFO1}" | sed -n 's|^.*size=\s\+\([0-9]\+\).*$|\1|p')
  LOOP1="$(losetup -f --show -o $((${START1} * 512)) --sizelimit $((${SIZE1} * 512)) "${IMGFILE}")"
  if [ $? -ne 0 ]; then
    errexit "Unable to create BOOT loop device"
  fi
}

rmloop1()
{
  if [ "${LOOP1}" != "" ]; then
    sync
    losetup -d "${LOOP1}"
    LOOP1=""
 fi
}

# create ROOT loop device
mkloop2()
{
  local INFO2=""
  local SIZE2=0
  local START2=0

  sync
  INFO2="$(sfdisk -d "${IMGFILE}")"
  START2=$(grep type=83 <<< "${INFO2}" | sed -n 's|^.*start=\s\+\([0-9]\+\).*$|\1|p')
  SIZE2=$(grep type=83 <<< "${INFO2}" | sed -n 's|^.*size=\s\+\([0-9]\+\).*$|\1|p')
  LOOP2="$(losetup -f --show -o $((${START2} * 512)) --sizelimit $((${SIZE2} * 512)) "${IMGFILE}")"
  if [ $? -ne 0 ]; then
    errexit "Unable to create ROOT loop device"
  fi
}

rmloop2()
{
  if [ "${LOOP2}" != "" ]; then
    sync
    losetup -d "${LOOP2}"
    LOOP2=""
  fi
}

# Mount Image partitions
mntimg()
{
  MNTED=TRUE
  if [ ! -d "${MNTPATH}/" ]; then
    mkdir "${MNTPATH}/"
    if [ $? -ne 0 ]; then
      errexit "Unable to make ROOT partition mount point"
    fi
  fi
  mkloop2
  mount "${LOOP2}" "${MNTPATH}/"
  if [ $? -ne 0 ]; then
    errexit "Unable to mount image ROOT partition"
  fi
  if [ ! -d "${MNTPATH}/boot/" ]; then
    mkdir -p "${MNTPATH}/boot/"
    if [ $? -ne 0 ]; then
      errexit "Unable to make BOOT partition mount point"
    fi
  fi
  mkloop1
  mount "${LOOP1}" "${MNTPATH}/boot/"
  if [ $? -ne 0 ]; then
    errexit "Unable to mount image BOOT partition"
  fi
}

umntimg()
{
  umount "${MNTPATH}/boot/"
  if [ $? -ne 0 ]; then
    errexit "Unable to unmount image BOOT partition"
  fi
  rmloop1
  umount "${MNTPATH}/"
  if [ $? -ne 0 ]; then
    errexit "Unable to unmount image ROOT partition"
  fi
  rmloop2
  rm -r "${MNTPATH}/"
  MNTED=FALSE
}

errexit()
{
  echo ""
  echo "$1"
  echo ""
  if [ "${MNTED}" = "TRUE" ]; then
    umount "${MNTPATH}/boot/" &> /dev/null
    umount "${MNTPATH}/" &> /dev/null
    rm -rf "${MNTPATH}/" &> /dev/null
  fi
  rmloop1
  rmloop2
  exit 1
}

LOOP1=""
LOOP2=""
MNTED=FALSE

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

if [ $(id -u) -ne 0 ]; then
  errexit "$0 must be run as root user"
fi

PGMNAME="$(basename $0)"
for PID in $(pidof -x -o %PPID "${PGMNAME}"); do
  if [ ${PID} -ne $$ ]; then
    errexit "${PGMNAME} is already running"
  fi
done

rsync --version &> /dev/null
if [ $? -ne 0 ]; then
  errexit "rsync not installed (run: apt-get install rsync)"
fi

if command -v systemctl > /dev/null && systemctl | grep -q '\-\.mount'; then
  SYSTEMD=1
elif [ -f /etc/init.d/cron ] && [ ! -h /etc/init.d/cron ]; then
  SYSTEMD=0
else
  errexit "Unrecognized init system"
fi

if [ ${SYSTEMD} -eq 1 ]; then
  ROOT_PART="$(mount | sed -n 's|^/dev/\(.*\) on / .*|\1|p')"
else
  if [ ! -h /dev/root ]; then
    errexit "/dev/root does not exist or is not a symlink"
  fi
  ROOT_PART="$(readlink /dev/root)"
fi

ROOT_TYPE=$(blkid "/dev/${ROOT_PART}" | sed -n 's|^.*TYPE="\(\S\+\)".*|\1|p')

ROOT_DEV="${ROOT_PART:0:(${#ROOT_PART} - 1)}"
if [ "${ROOT_DEV}" = "mmcblk0p" ]; then
  ROOT_DEV="${ROOT_DEV:0:(${#ROOT_DEV} - 1)}"
fi

PTUUID="$(blkid "/dev/${ROOT_DEV}" | sed -n 's|^.*PTUUID="\(\S\+\)".*|\1|p')"

DEVSIZE=$(blockdev --getsize64 "/dev/${ROOT_PART}")
BLKSIZE=$(blockdev --getbsz "/dev/${ROOT_PART}")
BLKCNT=$((${DEVSIZE} / ${BLKSIZE}))
INFO="$(df | grep /dev/root)"
DFKSIZE=$(awk '{print $2}' <<< "${INFO}")
DFKFREE=$(awk '{print $4}' <<< "${INFO}")
ROOTSIZE=$((${BLKCNT} * ${BLKSIZE}))
ROOTUSED=$(((${DFKSIZE} - ${DFKFREE}) * 1024))
IRFSMIN=$(((${ROOTUSED} + (${ADDBLK} * ${BLKSIZE}) + (${ONEMB} - 1)) / ${ONEMB}))
IRFSMAX=$(((${ROOTSIZE} + (${ONEMB} - 1)) / ${ONEMB}))

IMGFILE="$1"
if [ "${IMGFILE}" = "" ]; then
# Create Image file
  while :
  do
    echo ""
    read -r -e -i "${IMGFILE}" -p "Image file to create? " IMGFILE
    if [ "${IMGFILE}" = "" ]; then
      continue
    elif [[ ! "${IMGFILE}" =~ ^/mnt/.*$ && ! "${IMGFILE}" =~ ^/media/.*$ ]]; then
      echo ""
      echo "${IMGFILE} does not begin with /mnt/ or /media/"
      continue
    fi
    if [ -d "${IMGFILE}" ]; then
      echo ""
      echo "${IMGFILE} is a directory"
    elif [ -f "${IMGFILE}" ]; then
      echo ""
      echo -n "${IMGFILE} already exists, Ok to delete (y/n)? "
      while read -r -n 1 -s answer; do
        if [[ "${answer}" = [yYnN] ]]; then
          echo "${answer}"
          if [[ "${answer}" = [yY] ]]; then
            break 2
          else
            break 1
          fi
        fi
      done
    else
      break
    fi
  done
  IRFSSIZE=""
  while :
  do
    echo ""
    read -r -e -i "${IRFSSIZE}" -p "Image ROOT filesystem size (MB) [${IRFSMAX}]? " IRFSSIZE
    if [ "${IRFSSIZE}" = "" ]; then
      IRFSSIZE=${IRFSMAX}
      break
    elif [ ${IRFSSIZE} -ge ${IRFSMIN} ]; then
      break
    else
      echo ""
      echo "Requested image ROOT filesystem size (${IRFSSIZE}) is too small (Minimum = ${IRFSMIN})"
      IRFSSIZE=${IRFSMIN}
    fi
  done
  echo ""
  echo -n "Create ${IMGFILE} [${IRFSSIZE} MB] (y/n)? "
  while read -r -n 1 -s answer; do
    if [[ "${answer}" = [yYnN] ]]; then
      echo "${answer}"
      if [[ "${answer}" = [yY] ]]; then
        break
      else
        errexit "Aborted"
      fi
    fi
  done
  if [ -f "${IMGFILE}" ]; then
    rm "${IMGFILE}"
    if [ $? -ne 0 ]; then
      errexit "Unable to delete existing image file"
    fi
  fi
  ROOTEND=$((${ROOTBEG} + ((${IRFSSIZE} * ${ONEMB}) / 512) - 1))
  truncate -s $(((${ROOTEND} + 1) * 512)) "${IMGFILE}"
  if [ $? -ne 0 ]; then
    errexit "Unable to create image file"
  fi
# create image/partitions
  sync
  fdisk "${IMGFILE}" <<EOF > /dev/null
p
n
p
1
${BOOTBEG}
+${BOOTSIZEM}
t
c
p
n
p
2
${ROOTBEG}
${ROOTEND}
p
w
EOF

  mkloop1
  mkloop2
  mkfs.vfat "${LOOP1}" > /dev/null
  if [ $? -ne 0 ]; then
    errexit "Unable to create image BOOT filesystem"
  fi
  dosfsck "${LOOP1}" > /dev/null
  if [ $? -ne 0 ]; then
    errexit "Image BOOT filesystem appears corrupted"
  fi
  if [ "${ROOT_TYPE}" = "f2fs" ]; then
    mkfs.f2fs "${LOOP2}" > /dev/null
  else
    mkfs.ext4 -q -b ${BLKSIZE} "${LOOP2}" > /dev/null
  fi
  if [ $? -ne 0 ]; then
    errexit "Unable to create image ROOT filesystem"
  fi
  rmloop2
  rmloop1
# Initialise image PARTUUID
  fdisk "${IMGFILE}" <<EOF > /dev/null
p
x
i
0x${PTUUID}
r
p
w
EOF
# Create empty directories in image root partition
  mntimg
  mkdir "${MNTPATH}/dev/" "${MNTPATH}/media/" "${MNTPATH}/mnt/" "${MNTPATH}/proc/" "${MNTPATH}/run/" "${MNTPATH}/sys/" "${MNTPATH}/tmp/"
  if [ $? -ne 0 ]; then
    errexit "Unable to create image directories"
  fi
  chmod a+rwxt "${MNTPATH}/tmp/"
  umntimg
  echo ""
  echo "Starting full backup (for incremental backups, run: $0 ${IMGFILE})"
# END of create image/partitions
else

# Check existing Image
  if [[ ! "${IMGFILE}" =~ ^/mnt/.*$ && ! "${IMGFILE}" =~ ^/media/.*$ ]]; then
    errexit "${IMGFILE} does not begin with /mnt/ or /media/"
  fi
  if [ -d "${IMGFILE}" ]; then
    errexit "${IMGFILE} is a directory"
  elif [ ! -f "${IMGFILE}" ]; then
    errexit "${IMGFILE} not found"
  fi
  echo "Starting incremental backup to ${IMGFILE}"
fi

# rsync root partition
mntimg
sync
rsync -aDH --partial --numeric-ids --delete --force --exclude "${MNTPATH}" --exclude '/dev' --exclude '/media' --exclude '/mnt/*/*' --exclude '/proc' --exclude '/run' --exclude '/sys' \
--exclude '/tmp' --exclude 'lost\+found' --exclude '/etc/udev/rules.d/70-persistent-net.rules' --exclude '/var/lib/asterisk/astdb.sqlite3-journal' / "${MNTPATH}/"
if [[ $? -ne 0 && $? -ne 24 ]]; then
  errexit "Unable to create backup"
fi
sync
umntimg

-1

Otwórz terminal i wpisz „lsblk -f”.
Powinno to pokazać wszystkie podłączone urządzenia pamięci masowej.
Następnie wpisz „dd if = / dev / [NAZWA karty SD] bs = 1M”.
To zajmie trochę czasu, więc możesz chcieć uruchomić go w tle.
To jest dokładnie ten sam sposób, w jaki wykonuje się kopię zapasową karty SD w systemie Linux.


To tworzy kopię zapasową WSZYSTKO, nawet niepotrzebnych i niepożądanych plików.
IgorGanapolsky

3
Spowoduje to niespójne tworzenie kopii zapasowej, ponieważ w działającym systemie rzeczy zmieniły się podczas tworzenia kopii zapasowej!
Ingo,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.