English is not my mother tongue, this page may contain incorrect words or sentences.

urriellu.net => Projects => Software => LocalBackuper

LocalBackuper is an application written in C# which runs on mono designed for mounting an external hard drive, decrypt and mount it, clean old backups (when needed) and make new encrypted backups.

Why?

There are are a lot of backup systems: some of them very simple, some very complex, and I didn't like any of them. I also enjoy developing apps and I'm always thinking about reimplementing existing things... because I want, I'm not trying to create a better or more useful implementation. LocalBackuper doesn't pretend to be a solution for everyone, just for me exactly how I want it to work. If you want more features it could be updated but in that case choosing another backup system would be the right choice.

How it works

  • MakeBackups.sh is executed as root
    • Mounts, asks the password and decrypts the backups partition
    • Umounts some partitions that may be problematic when backuping
    • Runs LocalBackuper.exe
    • Umount previously mounted partition
  • LocalBackuper.exe (designed for being run directly, without MakeBackups.sh)
    • Files and directories being backuped, sorted by importance, are added to a list
    • Calculates the space used by previous backups
    • Calculates the space required for new backups
    • If there is not enough free space it begins to delete less valuable files from the oldest backup until there is enough space on disk or the oldest backup is completely removed for continue removing files from the second oldest backup (now the oldest one). Doing this you preserve the highest possible amount of complete backups and the oldest backup will be the only one incomplete (but you have new copies, so there is no problem)
    • Specified files and directories are copied to the backups directory. Each backup will be saved on its own directory named YEARMONTHDAY-NNN, being NNN an index useful when there are more than one backup per day.

Console output example:

$ /usr/local/bin/MakeBackups.sh
Decrypting backups HD...
Enter LUKS passphrase:
key slot 0 unlocked.
Command successful.
Mounting decrypted backups partition...
Unmounting some other things before backing up...
    [...]
Backing up...
Total space: 152619 MiB (149 GiB)
Used space: 117351 MiB (114 GiB)
Free space: 35268 MiB (34 GiB)
Needed space for the new backup: 20085 MiB (19 GiB)
We are keeping all the old backups :-D
Creating a new backup in /mnt/backups/backups-main_server/20070817000
        Copying /home/data to /mnt/backups/backups-main_server/20070817000/home_data
        Copying /home/Pictures to /mnt/backups/backups-main_server/20070817000/home_Pictures
        Copying /home/urriellu/.mailfilter to /mnt/backups/backups-main_server/20070817000/home_urriellu_.mailfilter
Unmounting backups partition...
Reencrypting backups partition...
You can turn off the backups partition now :-D

Take care of...

  • It works only on OSs that has got the required external binaries
  • MakeBackups.sh and LocalBackuper.exe must be run as root for being able to mount, decrypt and read files owned by anyone. Before any file is deleted it checks which path is going to be removed to avoid unknown bugs
  • It uses some external binaries such as du, df and rm. For example Directory.Delete() was reimplemented using rm because the CLR gave some problems deleting files named using a wrong charset. The rest of reasons are explained in the source code
  • The list of files and directories being backuped, the path to external binaries, the path to the encrypted partition and the path where the encrypted partition is mounted are all hardcoded in MakeBackups.sh and config.cs

Source code

MakeBackups.sh, 25 lines      [download]

  1. #!/bin/bash
  2.  
  3. #this script must be executed as root (chmod 740 <this_script.sh> is a good choice)
  4.  
  5. echo -e "Decrypting backups HD..."
  6. while [ ! -e /dev/mapper/backup_crypt ]; do
  7. cryptsetup luksOpen /dev/sdc1 backup_crypt
  8. done
  9.  
  10. echo -e "Mounting decrypted backups partition..."
  11. mount /dev/mapper/backup_crypt /mnt/backups
  12.  
  13. echo -e "Unmounting some other things before backing up..."
  14. #whatever you want
  15.  
  16. echo -e "Backing up..."
  17. /usr/bin/mono /usr/local/bin/LocalBackuper.exe
  18.  
  19. echo -e "Unmounting backups partition..."
  20. umount /mnt/backups/
  21.  
  22. echo -e "Reencrypting backups partition..."
  23. cryptsetup remove backup_crypt
  24.  
  25. echo -e "You can turn off the backups HD now :-D"
  26.  

Program.cs, 33 lines      [download]

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. namespace LocalBackuper {
  5.         class Program {
  6.                 static void Main(string[] args) {
  7.                         if(Environment.UserName == "root") {
  8.                                 Console.WriteLine("Total space: {0} MiB ({1} GiB)" , general.DriveInfo.TotalSpace / 1024 / 1024 , general.DriveInfo.TotalSpace / 1024 / 1024 / 1024);
  9.                                 Console.WriteLine("Used space: {0} MiB ({1} GiB)" , general.DriveInfo.UsedSpace / 1024 / 1024 , general.DriveInfo.UsedSpace / 1024 / 1024 / 1024);
  10.                                 Console.WriteLine("Free space: {0} MiB ({1} GiB)" , general.DriveInfo.FreeSpace / 1024 / 1024 , general.DriveInfo.FreeSpace / 1024 / 1024 / 1024);
  11.                                 Console.WriteLine("Needed space for the new backup: {0} MiB ({1} GiB)" , general.NewBackupSize / 1024 / 1024 , general.NewBackupSize / 1024 / 1024 / 1024);
  12.                                 if(general.NewBackupSize + config.KeepFreeSpace >= general.DriveInfo.TotalSpace) {
  13.  
  14. [...]

general.cs, 244 lines      [download]

  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Text;
  5. using System.Diagnostics;
  6. using System.IO;
  7. namespace LocalBackuper {
  8.         public static class general {
  9.                 private static UInt64 pNewBackupSize;
  10.                 /// <summary>
  11.                 /// Gets the size needed for the new backup.
  12.                 /// </summary>
  13.                 public static UInt64 NewBackupSize {
  14.  
  15. [...]

config.cs, 43 lines      [download]

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. namespace LocalBackuper {
  5.         public static class config {
  6.                 /// <summary>
  7.                 /// List of files and directories to be backuped
  8.                 /// </summary>
  9.                 /// BE CAREFUL: PATHS SHOULDN'T END WITH A SLASH ("/")
  10.                 public static string[] ListToBackup = {
  11.                         "/home/data" ,
  12.                         "/home/Pictures",
  13.                         "/home/urriellu.net" ,
  14.                         "/var/lib/mysql",
  15.  
  16. [...]