<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>https://beardedmaker.com/wiki/index.php?action=history&amp;feed=atom&amp;title=Backup_NAS_Mini</id>
		<title>Backup NAS Mini - Revision history</title>
		<link rel="self" type="application/atom+xml" href="https://beardedmaker.com/wiki/index.php?action=history&amp;feed=atom&amp;title=Backup_NAS_Mini"/>
		<link rel="alternate" type="text/html" href="https://beardedmaker.com/wiki/index.php?title=Backup_NAS_Mini&amp;action=history"/>
		<updated>2026-04-19T05:43:30Z</updated>
		<subtitle>Revision history for this page on the wiki</subtitle>
		<generator>MediaWiki 1.27.4</generator>

	<entry>
		<id>https://beardedmaker.com/wiki/index.php?title=Backup_NAS_Mini&amp;diff=2812&amp;oldid=prev</id>
		<title>Beard at 05:56, 8 August 2018</title>
		<link rel="alternate" type="text/html" href="https://beardedmaker.com/wiki/index.php?title=Backup_NAS_Mini&amp;diff=2812&amp;oldid=prev"/>
				<updated>2018-08-08T05:56:47Z</updated>
		
		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;div class=&amp;quot;redbox&amp;quot;&amp;gt;&lt;br /&gt;
Unfinished page...&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I wanted to build a small Network Attached Storage (NAS) that is small, portable, cheap, and and doesn't consume a lot of power. I decided to use a Raspberry Pi 2 with a 500GB mechanical hard drive attached via USB. The purpose of this project is to have my most important files backed up on a portable device that I can grab in case of a fire.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Hardware =&lt;br /&gt;
&lt;br /&gt;
== Parts list ==&lt;br /&gt;
&lt;br /&gt;
* Raspberry Pi 2 Model B ([https://www.raspberrypi.org/products/raspberry-pi-2-model-b/ link])&lt;br /&gt;
* 4GB Sandisk SD card ([https://www.google.com/search?q=sandisk+4gm+mini+sd+card&amp;amp;source=univ&amp;amp;tbm=shop&amp;amp;tbo=u&amp;amp;sa=X&amp;amp;ved=0ahUKEwiB1cK0_L3bAhU4BjQIHYQVDX0QsxgIKA&amp;amp;biw=1360&amp;amp;bih=662 link])&lt;br /&gt;
* 500GB 2.5 inch hard drive ([https://www.google.com/search?biw=1360&amp;amp;bih=662&amp;amp;tbm=shop&amp;amp;ei=hEQXW4nLMYS40PEP3vC88Ao&amp;amp;q=wd+2.5+inch+500gb+sata&amp;amp;oq=wd+2.5+inch+500gb+sata&amp;amp;gs_l=psy-ab.3...7549.9805.0.10148.5.5.0.0.0.0.78.273.5.5.0....0...1c.1.64.psy-ab..0.0.0....0.EbFCuk0_VQk link])&lt;br /&gt;
* SATA-to-USB adapter ([https://www.google.com/search?biw=1360&amp;amp;bih=662&amp;amp;tbm=shop&amp;amp;ei=30UXW4GjKqrA0PEPqsGZcA&amp;amp;q=WEme+USB+3.0+to+SATA+&amp;amp;oq=WEme+USB+3.0+to+SATA+&amp;amp;gs_l=psy-ab.3...2773.2773.0.2985.1.1.0.0.0.0.43.43.1.1.0....0...1c.1.64.psy-ab..0.0.0....0.tO9Rt9xzUhU link])&lt;br /&gt;
* LM2596S DC-to-DC buck converter ([https://www.google.com/search?biw=1360&amp;amp;bih=662&amp;amp;tbm=shop&amp;amp;ei=nkUXW9g74r3Q8Q_5sLf4CA&amp;amp;q=LM2596S&amp;amp;oq=LM2596S&amp;amp;gs_l=psy-ab.3..0.18061.18061.0.18356.1.1.0.0.0.0.46.46.1.1.0....0...1c.1.64.psy-ab..0.1.46....0.3n3WQkFguXI link])&lt;br /&gt;
* CD drive enclosure (thrift store)&lt;br /&gt;
* 12V DC power supply ([https://www.google.com/search?biw=1360&amp;amp;bih=662&amp;amp;tbm=shop&amp;amp;ei=E0UXW97SLaSM0PEPwZC_yA4&amp;amp;q=12v+laptop+ac+adapter+-19v&amp;amp;oq=12v+laptop+ac+adapter+-19v&amp;amp;gs_l=psy-ab.3...9711.10981.0.11085.5.5.0.0.0.0.48.206.5.5.0....0...1c.1.64.psy-ab..0.0.0....0.zSxuwLB_tV4 link])&lt;br /&gt;
* various parts (USB cable, nuts/bolts, etc.)&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span id=&amp;quot;Power_Supply&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;Power ==&lt;br /&gt;
&lt;br /&gt;
The Raspberry Pi requires a little more than 5V and the USB-to-SATA adapter requires 12V, so I'm using a 12V DC power supply and a DC-to-DC buck converter (LM2596S) to convert it to 5V. Notice the placement of glue on the SATA port (second photo below) to prevent things from coming loose. I also put glue on the potentiometer on the buck converter after dialing it in to about 5.4V.&lt;br /&gt;
&lt;br /&gt;
[[File:DSC00539.JPG|frameless|400px]]&lt;br /&gt;
[[File:DSC00679.JPG|frameless|400px]]&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;i&amp;gt;Note: the hard drives are different colors because I switched hard drives half way through the project.&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The whole power setup is wired like this:&lt;br /&gt;
&lt;br /&gt;
[ wiring diagram ]&lt;br /&gt;
&lt;br /&gt;
Another thing that I did was add a tactile button to the back as a way of shutting down and restarting the machine. I mapped it to GPIO04 on the Raspberry Pi. For software setup, see [[#offbtn|Off Button Script]].&lt;br /&gt;
&lt;br /&gt;
== Hard Drive ==&lt;br /&gt;
&lt;br /&gt;
The hard drive is a 500GB 2.5 inch mechanical drive, attached via USB with a SATA to USB adapter. I mounted it under the Raspberry Pi using 3D printed brackets ([https://www.thingiverse.com/thing:2976706 link]).&lt;br /&gt;
&lt;br /&gt;
[[File:DSC00478.JPG|frameless|400px]]&lt;br /&gt;
[[File:DSC00480.JPG|frameless|400px]]&lt;br /&gt;
&lt;br /&gt;
The adapter is a &amp;lt;i&amp;gt;WEme USB 3.0 to SATA Converter Adapter (model number 4328317644)&amp;lt;/i&amp;gt; that I bought from Amazon (here's a Google [https://www.google.com/search?biw=1360&amp;amp;bih=662&amp;amp;tbm=shop&amp;amp;ei=30UXW4GjKqrA0PEPqsGZcA&amp;amp;q=WEme+USB+3.0+to+SATA+&amp;amp;oq=WEme+USB+3.0+to+SATA+&amp;amp;gs_l=psy-ab.3...2773.2773.0.2985.1.1.0.0.0.0.43.43.1.1.0....0...1c.1.64.psy-ab..0.0.0....0.tO9Rt9xzUhU link]). I took the casing off of it and just used the bare PCB. The reason I chose this particular adapter is that it uses external power instead of being powered through the USB. The Raspberry Pi can only provide so much current. The adapter came with a 12V power supply, but I replaced it with higher current adapter.&lt;br /&gt;
&lt;br /&gt;
[[File:Hdd-usb-adapter.jpg|frameless|300px]]&lt;br /&gt;
[[File:DSC00535.JPG|frameless|400px]]&lt;br /&gt;
&lt;br /&gt;
I decided to solder the USB cable to the Pi instead of plugging it into the USB port. I found that I still needed to wire up all four USB pins to the Raspberry Pi because the adapter still expects there to be power on the USB. I also soldered the cable shielding to one of the USB anchor points on the Raspberry Pi.&lt;br /&gt;
&lt;br /&gt;
[[File:DSC00676.JPG|frameless|400px]]&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;i&amp;gt;Notice that I put kapton tape under the wire as well as on top.&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the USB wiring diagram:&lt;br /&gt;
&lt;br /&gt;
[ USB pinout diagram ]&lt;br /&gt;
&lt;br /&gt;
Wiring it up this way presents the risk of accidentally plugging something into the USB port in the back that is used for the hard drive, so I 3D printed a USB cover. The port that needs to be blocked is the top right next to the Ethernet port.&lt;br /&gt;
&lt;br /&gt;
[[File:DSC00747_EDIT.JPG|frameless]]&lt;br /&gt;
[[File:DSC00828.JPG|frameless]]&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;i&amp;gt;Not my design ([https://www.thingiverse.com/thing:2655623 link]).&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== LED Indicator ==&lt;br /&gt;
&lt;br /&gt;
I put an RGB LED on the front of the case as an indicator light.&lt;br /&gt;
&lt;br /&gt;
[[File:DSC00681.JPG|frameless|400px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;padding-right:10px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Here is the GPIO Pinout:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;nice&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;LED Pin&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th style=&amp;quot;width:140px;&amp;quot;&amp;gt;GPIO Pin&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;blue&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;GPIO23&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;red&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;GPIO18&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;GND&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;GND&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Here are the current ways this LED indicates status:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;nice&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Color&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Behavior&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th style=&amp;quot;width:140px;&amp;quot;&amp;gt;Meaning&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;blue&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;solid&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;system idle&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;blue&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;blink&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;backup in progress&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;red&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;blink&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;backup error occurred&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For software setup of the LED indicator, see [[#ledscript|LED Script]].&lt;br /&gt;
&lt;br /&gt;
== Enclosure ==&lt;br /&gt;
&lt;br /&gt;
The enclosure is simply an old external CD/DVD drive enclosure. I cut out a place in the back for the Raspberry Pi USB and Ethernet connectors. I glued on a piece of black acrylic on the front of the case as a face plate. The internals are mounted to a piece of MDF board which is bolted in from the bottom. It was really just trial and error figuring out how to mount everything. I ended up making 3D printed parts for the hard drive.&lt;br /&gt;
&lt;br /&gt;
[[File:DSC00682.JPG|frameless|400px]]&lt;br /&gt;
[[File:DSC00680.JPG|frameless|400px]]&lt;br /&gt;
&lt;br /&gt;
Notice the stand-offs on the Raspberry Pi have segments of drinking straw on them. This was simply to ensure the nuts were put on at exactly the same height; the straw segments were all cut exactly the same length and were used as guides. I could have cut them off, but it wasn't necessary.&lt;br /&gt;
&lt;br /&gt;
[[File:DSC00475.JPG|frameless|400px]]&lt;br /&gt;
[[File:DSC00827.JPG|frameless|400px]]&lt;br /&gt;
&lt;br /&gt;
= Software =&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span id=&amp;quot;OperatingSystem&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;Operating System ==&lt;br /&gt;
&lt;br /&gt;
I used a minimal install of Raspbian Jessie. You can download the latest version of Raspbian [https://www.raspberrypi.org/downloads/raspbian/ here]. There are several configurations I setup for this project. I do these tasks as root.&lt;br /&gt;
&lt;br /&gt;
I installed all the packages that I'm going to use in this project:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
apt-get install python python-rpi.gpio python-pylibacl python-pylibattr python-pyxattr rdiff-backup ssmtp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I added the user and the group that will be performing the backup (I typically don't use the system's built-in accounts):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
# Assuming your password is 'PICKLES', but you should run passwd manually and enter the password in the prompt&lt;br /&gt;
useradd -m backer&lt;br /&gt;
echo -e &amp;quot;PICKLES\nPICKLES&amp;quot; | passwd backer&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I created a mount point for the backups and setup permissions:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
mkdir /backups&lt;br /&gt;
chown backer:backer /backups&lt;br /&gt;
chmod 770 /backups&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I setup the drive:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
# Find out the drive name&lt;br /&gt;
# Mine was /dev/sda but for basic copy/paste safety I will use /dev/sdx in these examples&lt;br /&gt;
fdisk -l | grep &amp;quot;^Disk&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Create the partition /dev/sdx1&lt;br /&gt;
echo -e &amp;quot;n\np\n1\n\n\n\nw\n&amp;quot; | fdisk /dev/sdx&lt;br /&gt;
&lt;br /&gt;
# Create file system with 0% reserved blocks on sdx1&lt;br /&gt;
mkfs -t ext4 -m 0 -L Backups01 /dev/sdx1&lt;br /&gt;
&lt;br /&gt;
# Add the mount to fstab. Importantly, I'm using the 'nofail' and 'nobootwait' options.&lt;br /&gt;
echo 'LABEL=&amp;quot;Backups01&amp;quot; /backups   ext4    defaults,nofail,nobootwait  0  0' &amp;gt;&amp;gt;/etc/fstab&lt;br /&gt;
mount -a&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On the &amp;lt;b&amp;gt;source&amp;lt;/b&amp;gt; machine (the remote machine that has my files) I also create the user:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
# Assuming your password is 'PICKLES'&lt;br /&gt;
useradd -m backer&lt;br /&gt;
echo -e &amp;quot;PICKLES\nPICKLES&amp;quot; | passwd backer&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The tricky part is making sure that backer has read permissions on all the files that you need to backup, and read/execute permissions on folders. So if I assume your files are contained in /home/timmy/myfiles (on the &amp;lt;b&amp;gt;source&amp;lt;/b&amp;gt; machine), you might do:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
# Add group ownership to all files/folders&lt;br /&gt;
chown -R :backer /home/timmy/myfiles&lt;br /&gt;
# Add read/execute to all folders&lt;br /&gt;
find /home/timmy/myfiles -type d -print0 | xargs -0 chmod g+rx  &lt;br /&gt;
# Add read to all files&lt;br /&gt;
find /home/timmy/myfiles -type f -print0 | xargs -0 chmod g+r&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can set permissions on a more granular level if you need to. Don't do this on system files.&lt;br /&gt;
&lt;br /&gt;
[ incomplete: source server ssh config and certificate ]&lt;br /&gt;
&lt;br /&gt;
== Backup Script ==&lt;br /&gt;
&lt;br /&gt;
This is the main script that I wrote to perform the backups. Make sure you've installed the packages mentioned in [[#OperatingSystem|Operating System]].&lt;br /&gt;
&lt;br /&gt;
Here's the idea:&lt;br /&gt;
* The &amp;lt;b&amp;gt;backup&amp;lt;/b&amp;gt; server has a cron job that performs the backup process on a schedule.&lt;br /&gt;
* The backup process logs in remotely to the &amp;lt;b&amp;gt;source&amp;lt;/b&amp;gt; server using rdiff-backup.&lt;br /&gt;
* Rdiff-backup uses SSH. We will be able to log in without a password prompt by using certificate authentication.&lt;br /&gt;
* We define &amp;lt;i&amp;gt;included&amp;lt;/i&amp;gt; and &amp;lt;i&amp;gt;excluded&amp;lt;/i&amp;gt; files and directories to control what get backed up incrementally.&lt;br /&gt;
* Each backup process generates a log file and sends text and email notifications if an error occurs.&lt;br /&gt;
&lt;br /&gt;
As root, I created the directory structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p /scripts/backup-system/config /scripts/config /logs/backups&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
crontab&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
10 4    * * * root /scripts/backup-system/backup-run.sh -y&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;fix&amp;quot;&amp;gt;&lt;br /&gt;
Re-upload scripts after I've fixed everything.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
[ incomplete ]&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span id=&amp;quot;ledscript&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;LED Script ==&lt;br /&gt;
&lt;br /&gt;
== Backup Status Script ==&lt;br /&gt;
&lt;br /&gt;
== Restore Script ==&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span id=&amp;quot;TextandEmailMessaging&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;Text and Email Messaging ==&lt;br /&gt;
&lt;br /&gt;
I wanted the system to send me text and email notifications.&lt;br /&gt;
&lt;br /&gt;
Make sure you've installed the packages mentioned in [[#OperatingSystem|Operating System]].&lt;br /&gt;
&lt;br /&gt;
crontab&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
00 12   * * * root /scripts/scheduled-messages.sh&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[ incomplete ]&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span id=&amp;quot;offbtn&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;Off Button Script ==&lt;br /&gt;
&lt;br /&gt;
I added a tactile button to GPIO4 on the Raspberry Pi to act as a power button. When held for a certain number of seconds, it executes the shutdown command. This allows my [[#ShutdownScript|Shutdown Script]] to wait for a backup to complete before powering the system down.&lt;br /&gt;
&lt;br /&gt;
Here is the Python script:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/python&lt;br /&gt;
#&lt;br /&gt;
# Script to shutdown Raspberry Pi when GPIO input is held.&lt;br /&gt;
# Connect a button between ground (GND) and the GPIO pin&lt;br /&gt;
# that you specify below.&lt;br /&gt;
#&lt;br /&gt;
# If you run this script from your /etc/rc.local file, it&lt;br /&gt;
# will be running as root, which eliminates the need to &lt;br /&gt;
# enter a password to elevate privileges. Otherwise, the&lt;br /&gt;
# sudo command will ask for a password before it will&lt;br /&gt;
# execute shutdown.&lt;br /&gt;
&lt;br /&gt;
import RPi.GPIO as GPIO&lt;br /&gt;
import sys,os,signal,time&lt;br /&gt;
&lt;br /&gt;
# GPIO pin number&lt;br /&gt;
btn = 4&lt;br /&gt;
&lt;br /&gt;
# Button must be held for this many seconds&lt;br /&gt;
delay = 3.0&lt;br /&gt;
&lt;br /&gt;
def sense_input(btn,delay):&lt;br /&gt;
&lt;br /&gt;
  try:&lt;br /&gt;
    # Wait for button press&lt;br /&gt;
    GPIO.wait_for_edge(btn, GPIO.FALLING)&lt;br /&gt;
&lt;br /&gt;
    count = 0&lt;br /&gt;
    while True:&lt;br /&gt;
      if GPIO.input(btn) == False:&lt;br /&gt;
        if count &amp;lt; delay:&lt;br /&gt;
          count = count + 1&lt;br /&gt;
          time.sleep(0.1)&lt;br /&gt;
          continue&lt;br /&gt;
        else:&lt;br /&gt;
         # Shutdown system&lt;br /&gt;
         os.system(&amp;quot;sudo shutdown -h now&amp;quot;)&lt;br /&gt;
         os._exit(-1)&lt;br /&gt;
      else:&lt;br /&gt;
          try:&lt;br /&gt;
            GPIO.cleanup()&lt;br /&gt;
          except:&lt;br /&gt;
            pass&lt;br /&gt;
          time.sleep(0.1)&lt;br /&gt;
          break&lt;br /&gt;
&lt;br /&gt;
  except KeyboardInterrupt:&lt;br /&gt;
    try:&lt;br /&gt;
      GPIO.cleanup()&lt;br /&gt;
    except:&lt;br /&gt;
      pass&lt;br /&gt;
    os._exit(-1)&lt;br /&gt;
&lt;br /&gt;
  except:&lt;br /&gt;
    pass          &lt;br /&gt;
        &lt;br /&gt;
delay = delay*10&lt;br /&gt;
while True:&lt;br /&gt;
  GPIO.setmode(GPIO.BCM)&lt;br /&gt;
  GPIO.setup(btn, GPIO.IN, pull_up_down=GPIO.PUD_UP)&lt;br /&gt;
  sense_input(btn,delay)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Assuming you save this to &amp;lt;code&amp;gt;/scripts/off-button.py&amp;lt;/code&amp;gt; go ahead and make it executable:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
chmod a+x /scripts/off-button.py&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then add it to &amp;lt;code&amp;gt;/etc/rc.local&amp;lt;/code&amp;gt; so it runs on startup. Enter the command above the &amp;lt;code&amp;gt;exit 0&amp;lt;/code&amp;gt; line so that it looks like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
# ... existing rc.local stuff ...&lt;br /&gt;
&lt;br /&gt;
python /scripts/off-button.py &amp;amp;&lt;br /&gt;
exit 0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;span id=&amp;quot;ShutdownScript&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;Shutdown Script ==&lt;br /&gt;
&lt;br /&gt;
I wanted to have the system wait for a backup to complete if the system is shutdown while a backup is in progress. I created this script called &amp;lt;code&amp;gt;wait-for-backup&amp;lt;/code&amp;gt;. It also sends a text message on shutdown (see [[#TextandEmailMessaging|Text and Email Messaging]]):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#&lt;br /&gt;
# Shutdown script for backup server.&lt;br /&gt;
# Waits for rdiff-backup to finish.&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
log=/logs/server-shutdown.log&lt;br /&gt;
&lt;br /&gt;
mount -oremount,rw /&lt;br /&gt;
echo &amp;quot;[`date`] TEST: Shutdown issued. Waiting for rdiff-backup to stop...&amp;quot; &amp;gt;&amp;gt;$log&lt;br /&gt;
&lt;br /&gt;
/scripts/sms.sh &amp;quot;backup2&amp;quot; &amp;quot;system shutdown ( `date` )&amp;quot;&lt;br /&gt;
sleep 20&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;[`date`] TEST: Done waiting.&amp;quot; &amp;gt;&amp;gt;$log&lt;br /&gt;
mount -oremount,ro /&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once you have this script located in &amp;lt;code&amp;gt;/etc/init.d&amp;lt;/code&amp;gt; you can create a symbolic link in the appropriate rc directories. Make sure this script is run before any of the VirtualBox services are stopped. For my server, I made it &amp;lt;b&amp;gt;K64&amp;lt;/b&amp;gt;. Make sure wait-for-backup is executable.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
sudo chmod 755 /etc/init.d/wait-for-backup&lt;br /&gt;
sudo ln -s /etc/init.d/wait-for-backup /etc/rc0.d/K64stop-vms&lt;br /&gt;
sudo ln -s /etc/init.d/wait-for-backup /etc/rc6.d/K64stop-vms&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;If you're using Systemd&amp;lt;/b&amp;gt; you need to do this differently.&lt;br /&gt;
&lt;br /&gt;
You can put a script in the Systemd system-shutdown script folder. It is located in a different place on different Linux distributions:&lt;br /&gt;
* Debian: &amp;lt;code&amp;gt;/lib/systemd/system-shutdown&amp;lt;/code&amp;gt;&lt;br /&gt;
* Other: &amp;lt;code&amp;gt;/usr/lib/systemd/system-shutdown&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Put the wait-for-backup script in that folder and make sure it's executable.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;red-box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[ THIS SECTION NEEDS TO BE CORRECTED ]&lt;br /&gt;
&lt;br /&gt;
You actually make script &amp;lt;code&amp;gt;/scripts/backup-system/shutdown-wait-for-backup.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
contents&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then make file &amp;lt;code&amp;gt;/lib/systemd/system/wait-for-backup.service&amp;lt;/code&amp;gt; with:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
contents&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
&lt;br /&gt;
* https://www.tecmint.com/rdiff-backup-remote-incremental-backup-for-linux/&lt;br /&gt;
* https://www.howtoforge.com/linux_rdiff_backup&lt;br /&gt;
* http://www.linuxproblem.org/art_9.html&lt;br /&gt;
* http://www.nongnu.org/rdiff-backup/examples.html&lt;/div&gt;</summary>
		<author><name>Beard</name></author>	</entry>

	</feed>