Awasu » Backing up a Banana Pi
Sunday 4th October 2015 6:43 PM []

Now we have our system running and nicely configured, we want to back everything up[1]Raspberry Pi's have something of a reputation for corrupting SD cards, although I haven't had problems with any of my Banana Pi's, even after pulling the plug on them a few times..

We can run the same Win32DiskImager tool we used at the start of this tutorial, except this time, we click on the Read button, to read the SD card data and save it in an image file.

Nice and easy, but unfortunately, there are two problems with this.

Firstly, Win32DiskImager makes a copy of the entire SD card, even the parts that are not being used. If we take a look at our root file system[2]This holds the operating system, OMV, and other support files, but doesn't include our NAS data files., we can see that it's only using about 1.6 GB:

but Win32DiskImager produced a 7.5 GB image file[3]This is because I'm using an 8 GB SD card.! 🙁

While we could live with this, the second problem is a show-stopper: SD cards are not all exactly the same size[4]An 8 GB card will only be approximately 8 GB in size., so if we try to restore our backup image to an SD card that is even 1 byte too small, Win32DiskImager will refuse to write it out, rendering our backup useless.

Shrinking the backup image file

The way to work around this problem is to reduce the size of the backup image file.

We can see above that our root partition is 3.4 GB, of which only about 1.6 GB is being used, so the layout of the image file will look like something this:

So, we could safely shrink the file down to about 3.5GB, thus discarding all the unused space at the end of the file:

Now, we will definitely be able to restore it to another 8GB SD card. Indeed, it will even restore to a 4GB card!

However, with a little bit more work, we can make the backup image even smaller.

Shrinking the backup image file even more

If we have only 1.6 GB of actual data on the SD card, it would be nice to have only that in the backup image file, not the entire 3.4 GB partition. However, we can't just shrink the image file down to 1.6 GB, because the file data will be scattered throughout the partition, something like this:

If we shrink the image file down to 1.6 GB, we would lose the file data lying at the end of the partition! So, what we want to do is shuffle all the file data down to the start of the partition, like this:

Now, we can shrink the partition so that it fits snugly around the data[5]We will see later why we want to have a bit of extra space.:

We can then safely shrink the image file down to fit around the partition:

So, that's the theory - now let's actually do it on our SD image file.

Load the image file

First, we need to load our image file as a (loopback) device[6]We need to do this because fdisk only works with devices.:

We enable loopback, then request a device to be assigned to us. In this case, we received /dev/loop0.

Then we attach the image file to the device we were assigned, then load the partitions in that image file.

If we check the /dev/ directory, we can see that there is a /dev/loop0 entry (that represents the image file) and 2 entries for the partitions in the image file[7]The first partition is the boot partition, a small bootstrap loader, the second is the main root partition..

Running fdisk, we can see these partitions, and importantly, where they start and end on the disk.

Rearrange the file system

We can now rearrange the file system, so that everything is at the start of the partition:

For safety, we check the file system's integrity before and after the operation.

Note that while we are only using about 1.6 GB of space, we resize the the file system to be a little bit larger. We'll see later why this is a good idea.

resize2fs reports that the file system is now 524288 blocks in size, and given that a block is 4K in size[8]As reported earlier in the resize2fs output., the total size is 524288 x 4K = 2097152 K = 2 GB (i.e. as we requested).

Resize the partition

We can now shrink the partition down to fit around the file system. We do this by deleting the existing partition, then creating a new, smaller one[9]If your disk is larger than 2 TB, you will need to use parted to do this.. It's safe to do this because we are simply updating the disk's partition table (i.e. its record of where each partition starts and ends on the disk), we are not touching any of the actual data in the partition.

When we create the new partition, we leave the start sector where it is, and set the end sector based upon its size (2 GB).

After the resize has finished, we check the file system again, to make sure we haven't accidentally lost any data.


Truncate the image file

Finally, we can now shrink the image file down to fit around the partition. To calculate how large the file needs to be, we need to find out how many sectors are being used by the partition:

The End value for the last partition is 4317183, but this is a sector number, which is 0-based, so the number of sectors being used is 1 bigger i.e. 4317184.

The sector size is 512 bytes, so the total number of bytes is 4317184 x 512 = 2210398208, and this is the size we want to truncate the image file to:

We now have a backup of our SD card that's a little over 2 GB in size, a saving of over 5 GB :clap:

Restoring a backup image

If the unthinkable happens and the bPi's SD card becomes unusable, we can simply use Win32DiskImager to write out the backup image file to another SD card, pop it into the bPi and it should boot up exactly as it was before.

However, there is one important thing to keep in mind. After booting up the restored image, if we take a look at our file systems, we can see that the root partition is almost full:

This is because we reduced the size of the partition in the backup image file, so that's what got restored. If we leave the bPi running like this, it will run into problems if the root partition fills up[10]This is why we left some extra space when we shrunk the file system above., so we need to embiggen the size of this partition, using the same technique as above:

By accepting the default value for the last sector, the new partition will take up all the available space (since this partition is the last one on the disk).

Reboot the bPi, to allow the new partition table to be installed, and when it comes back up, resize the file system to take up all the available space:

« Sending emails from a Banana Pi without an internet connection

Tutorial index

   [ + ]

1. Raspberry Pi's have something of a reputation for corrupting SD cards, although I haven't had problems with any of my Banana Pi's, even after pulling the plug on them a few times.
2. This holds the operating system, OMV, and other support files, but doesn't include our NAS data files.
3. This is because I'm using an 8 GB SD card.
4. An 8 GB card will only be approximately 8 GB in size.
5. We will see later why we want to have a bit of extra space.
6. We need to do this because fdisk only works with devices.
7. The first partition is the boot partition, a small bootstrap loader, the second is the main root partition.
8. As reported earlier in the resize2fs output.
9. If your disk is larger than 2 TB, you will need to use parted to do this.
10. This is why we left some extra space when we shrunk the file system above.

8 Responses to this post

Hello, great tutorial indeed.
However I didn't find the answer to my issue... It is about OMV plugins.
I couldn't install the "miniDLNA" plugin even if it was reachable from the plugin window in the OMV web enviroment.
It just gaves me an error and I couldn't install it.
Is there maybe a manual way to install that tool and configure in the terminal? Would it be then possible to manage it in the OMV web enviroment?
I'm using BPi (not Pro) and the OMV version 2.1 image from Lemaker site.

Thanks,
Dunav

I didn't need to install any plugins myself, but I did notice a "openmediavault-omvextrasorg_0.6.22.1_all.deb" file in the /root directory that might be of use.

Great instruction, very helpful indead.
I took a slightly different route, but couldn't have done it without this article.
read image from sd-card with win32DiskImager.
upload bananapi.img with ftp (bin)
fdisk -l /mnt/ssd/bananapi.img
122880 * 512 bytes = 62914560
losetup --offset 62914560 /dev/loop0 /mnt/ssd/bananapi.img
e2fsck -f /dev/loop0
resize2fs -f /dev/loop0 8000M
e2fsck -f /dev/loop0
fdisk /mnt/ssd/bananapi.img
d
2
n
p
2
122880 (first sector)
+8000M (last sector)
w
losetup -d /dev/loop0
(end sector 16506879 * 512)
truncate --size 8451522048 /mnt/ssd/bananapi.img
download bananapi.img with ftp (bin)
write to sd-card with win32DiskImager

Hello, I've tried to reduce the size of my image but when I run partx -a /dev/loop0 it mounts the image and I can't continue as e2fsck is telling me that I have mounted /dev/loop0p1 🙁
What I'm doing wrong?
Thanks in advance for your help.

partx doesn't mount the partitions, it just reads what's in the disk image and creates entries in /dev/ for them. If your partx has somehow automatically mounted the partitions, then yes, e2fsck will refuse to proceed. If you unmount the partitions, you should be right.

Thanks Taka but I already tried it and whenever I unmount the partitions I can't access /dev/loop0. I think it could be because of my image, maybe it is corrupted.

Hello again, I already solved the problem. I was using LXDE with Debian Jessie and I disabled automount in PCmanFM (PCManFM->Edit->Preferences->Volume Management->uncheck automunt options). Now I'm able to shrink my images.
Thanks anyway!
BR

No worries, glad you worked it out. I don't know so much about these new-fangled GUI thingies... 🙂

Have your say