Script-keten
De Raspberry Pi detecteert via het udev-systeem wanneer een iPhone op de usb-poort wordt aangesloten, en zet via drie opeenvolgende scripts het back-uppen in gang.
rsync -v -a ~/usr/mnt ~/iphone-backups/ 0753abcd7bbcbd4f8f0 bd8776655443322110011
Afhankelijk van het aantal bestanden duurt het archiveren van een paar minuten tot uren. Rsync zet voor iedere directory en ieder bestand een statusregel op de terminal. Aan het eind koppel je het bestandssysteem van de iPhone weer los en maak je de pairing ongedaan: fusermount -u ~/usr/mnt idevicepair --debug unpair
GEAUTOMATISEERDE BACK-UP
Je kunt de back-up elke keer wanneer het udev-systeem een iPhone op een van de usb-poorten identificeert automatisch laten uitvoeren. Dat wordt voornamelijk gedaan door het Python3-script /home/pi/ backup-iphone.py . Dat vindt de iPhone met behulp van de uitvoer van het commando lsusb, koppelt hem aan de Raspberry Pi met idevicepair, mount het bestandssysteem van de iPhone met ifuse in het pad /home/pi/usr/mnt/ en kopieert met rsync alles wat de bibliotheek libimobiledevice op de iPhone toegankelijk maakt naar de sd-kaart van de Raspberry Pi in de directory /home/pi/iphone-backups/. Het Python-script schrijft zijn uitvoer met de rechten van de gebruiker pi naar het bestand /home/pi/log.txt. Zorg er daarom voor dat dit bestand toebehoort aan de gebruiker pi en de groep pi: sudo chown pi:pi ~/log.txt
Het Python-script wordt niet direct gestart via de udev-rule en met systeemrechten, maar indirect via de shell-scripts /home/pi/udev-runs-this.sh en /home/pi/backup-iphone.sh. Op die manier wordt de back-up uitgevoerd met de rechten van de gebruiker pi, zodat je de foto’s later als gebruiker pi bijvoorbeeld kunt bekijken met een fotoviewer.
Bovendien zorgt de keten van scripts ervoor dat het udev-systeem bij lange back-upprocessen niet wordt vertraagd. De bijbehorende commandoketen komt via een pipe bij het at-commando terecht, zodat udev slechts kort wordt gebruikt om de back-up te activeren. Het at-commando behoort niet tot het Raspberry Pi OS, dus dat moet je apart installeren: sudo apt-get install at
Het installeren kost even wat tijd omdat een hele zwik aan andere pakketten mee geïnstalleerd wordt.
Controleer dan of het automatisch back-uppen werkt. Start het script /home/pi/backup-iphone. sh handmatig. Vervolgens kun je het Python-script
back-up-iphone.py aan het werk zien door in een terminalvenster tail -f /home/pi/log.txt in te typen. Wanneer je voor een tweede back-up dezelfde iPhone gebruikt als bij het handmatig back-uppen, zou die tweede keer een stuk sneller moeten verlopen – als er geen nieuwe foto’s en video’s bijgekomen zijn.
Justin Pearson heeft uitvoerig gedocumenteerd hoe je de benodigde udev-rules opstelt. Maar als je de instructies in dit artikel gevolgd hebt, staan die allemaal al op hun plaats, maar zijn ze alleen nog niet actief. Om de wijzigingen toe te passen, hoef je ze alleen maar door udevadm en de udev- en usbmux-daemons in te laten lezen:
sudo udevadm control --reload-rules sudo service udev restart sudo service usbmuxd restart
Omdat usbmuxd en udev na een herstart van de Raspberry Pi niet correct geïnitialiseerd worden, kun je dat oplossen met een extra regel in /etc/rc.local: sudo nano /etc/rc.local
Voeg deze regel onderaan toe: service udev restart
Als je de iPhone dan aansluit, zal de nieuwe udev-rule het script /home/pi/udev-runs-this.sh activeren. Dat start /home/pi/backup-iphone.sh als gebruiker pi en dat op zijn beurt weer het Python-script backup-iphone.py. Voor het ontgrendelen van de iPhone heb je een tijdslimiet van ongeveer twee minuten voordat het script het opgeeft. Dat derde back-upproces zou eveneens snel moeten verlopen als er geen nieuwe bestanden bijgekomen zijn. Je kunt het einde van de back-up in het logbestand herkennen aan het feit dat het pairen met de iPhone wordt afgebroken.
Dat is nodig omdat de scripts aan de hand van de UDID slechts één iPhone tegelijk kunnen verwerken. Pas als de huidige is afgemeld en het pairen is afgesloten, kun je de volgende aansluiten. Dat is wel een beetje vervelend, omdat je voor elk nieuw back-upproces de vertrouwensvraag van de iPhone moet beantwoorden.
Rsync maakt bij het back-uppen een archief aan en schrijft daar dan alles in wat hij op de iPhone kan lezen. De foto’s en video’s komen in de directory ~/iphone-backups/UDID/mnt/DCIM terecht. Wanneer je foto’s of video’s van de iPhone verwijdert, bijvoorbeeld om ruimte vrij te maken, blijven die bestanden op de Raspberry Pi behouden. Je kunt het geheugen van de iPhone echter steeds opnieuw vullen
en handmatig legen. Als het materiaal op de Raspberry Pi gearchiveerd is, hoef je geen nieuwe iPhone te kopen omdat het geheugen door de vele foto’s en video’s vol raakt.
KNIPPERLICHTEN
Als je de ledbalk Blinkt! wilt gebruiken, zet die dan zo op de pinheader van de Raspberry Pi dat de zijde met de afgeronde hoeken naar buiten wijst. De belettering op de Blinkt! staat dan in dezelfde richting als de belettering op het Pi-board. Afhankelijk van de Pi-behuizing kan een 40-pins stacking-header nodig zijn om de GPIO-pinnen te verlengen (circa 2,50 euro).
Installeer de Blinkt!-software op de Raspberry Pi. Die kun je als ziparchief downloaden van GitHub (zie de link op deze pagina). Zo ziet een kleine Blink!-test eruit: python2 -c 'from blinkt import set_pixel, show, clear ; import time ; set_pixel(0,255,255,255,.1) ; show() ; time.sleep(2) ; clear()'
Led 1 licht dan kort op. Het Python-script backup-iphone.py schakelt achtereenvolgens de leds 1 tot 6 in, overeenkomstig de in het script afgewerkte functies: lock-bestand aanmaken (back-upproces getriggerd), lsusb (iPhone identificeren), idevicepair (iPhone pairen), ifuse (bestandssysteem mounten), rsync (back-uppen), fusermnt (bestandssysteem unmounten), idevicepair unpair (pairen afsluiten, lock-bestand verwijderen).
Vooral de tweede en vierde led zijn belangrijk. Wanneer de tweede led blauw is, wacht de Pi tot je de vertrouwensvraag op de iPhone bevestigt en de ontgrendelingscode intoetst. En zolang het back-uppen duurt, is de vierde led blauw. Gedurende die tijd mag je de iPhone in ieder geval niet loskoppelen van de Raspberry Pi om fouten in het bestandssysteem op de sd-kaart van de Pi te voorkomen. Als alles goed gaat, zullen aan het eind zes leds groen zijn. Dan kun je de iPhone loskoppelen. Omdat die gebeurtenis ook door udev gedetecteerd wordt, zet een tweede udev-rule alle leds kort op wit en uiteindelijk helemaal uit.
PROBLEEMPJES
Het script backup-iphone.py haalt met idevicepair list de UDID van de iPhone op en maakt een subdirectory met dezelfde naam in de back-up-directory aan. Na afloop wordt het pairen afgesloten met het commando idevicepair unpair. Wanneer dat mislukt (bijvoorbeeld omdat je de iPhone te snel hebt losgekoppeld), kan het commando idevicepair bij latere back-upsessies met andere iPhones soms meer dan één UDID opleveren. Dan maakt het backup-script directorynamen aan die uit twee of meer UDID’s bestaan, namelijk die van de huidige iPhone en die van het niet afgemelde apparaat. Op die manier raken nieuwe archieven door elkaar. Die fout treedt ook op wanneer je een iPad op de Raspberry Pi aansluit. De scripts zijn daar namelijk niet op berekend, zodat dan alleen het pairen werkt en verder niets.
Oplossing 1: om het probleem te verhelpen is het voldoende om de betreffende iPhone opnieuw aan te sluiten en daarmee het unpair-commando alsnog uit te voeren. Eventueel wordt er een nieuwe directory met de juiste naam aangemaakt en start het archiveringsproces van voren af aan.
Oplossing 2: als de corresponderende iPhone niet beschikbaar is (bijvoorbeeld omdat zoonlief met de niet afgemelde iPhone vertrokken is), kun je oplossing 2 gebruiken. Het pairen wordt genoteerd in het bestand /var/lib/lockdown/UUID.plist. Dat kun je probleemloos verwijderen, user-rechten zijn daarvoor al voldoende. Als je per ongeluk je iPad aansluit, werkt alleen die tweede oplossing.
Wanneer je de fout te laat ontdekt, kan het zijn dat het nieuwe archief niet alle foto’s en video’s bevat als die met de verkeerde naam. Dat gebeurt wanneer de foto’s en video’s in de map met de verkeerde naam terechtkomen en vervolgens op de iPhone worden verwijderd. Wanneer je daarna een nieuw archief met de juiste directorynaam start, zal die niet alle foto’s en video’s bevatten die met de iPhone gemaakt zijn. Om het probleem op te lossen, kun je de ontbrekende bestanden handmatig uit de verkeerde archiefdirectory naar de juiste kopiëren. Wanneer je zeker weet dat de nieuwe directory alle gewenste bestanden bevat, kun je de directory met de verkeerde naam handmatig verwijderen.
CONCLUSIE
Een van onze back-upsystemen draait al meer dan een jaar probleemloos op een Raspberry Pi 3B+ met Raspbian Stretch. We zijn indertijd begonnen met dat systeem voor iPhones met iOS 12. Inmiddels werken die iPhones na diverse updates met iOS 13.6 en loopt het archiveren gewoon door.
Op andere 3B+-exemplaren en op een Raspberry Pi 4 werkt het back-upsysteem met het huidige Rasberry Pi OS (Debian Buster). Ook daarmee kun je zonder meer back-ups maken van verschillende iPhone-modellen met iOS 12.x en 13.x, waaronder de iPhone 6, 6s, 8, SE en X.