Thursday, March 20, 2014

Autoconf Macros to Check for C++11 Features in the Header

C++11 introduces a lot of improvements and new features to the C++ language and the C++ Standard Library. Compilers and libraries are still implementing such features and it is likely your toolchain is still missing some piece, even though the ones I am using (GCC and CLang) are catching up quickly.

While on the one hand the GNU Build System is mostly used to build C projects and an historical lack of C++ macros is suffered, on the other hand there were no C++11 specific macro to check for library compliance.

For this reason, I began writing my own set of macros some weeks ago starting from what I needed at the time: C++11 features in the <functional> header. So far, I have written the following macros which cover all the new C++11 features in that header:

All the macros except AX_CXX_HAVE_PLACEHOLDERS were submitted to the GNU Autoconf Archive some weeks ago and are already available for use: just follow the link on the macro name, download the m4 file and use it. I submitted AX_CXX_HAVE_PLACEHOLDERS this morning and I expect it to be available shortly: I will update this post as soon as this macro has been accepted.

For those who want to contribute to this set of macros, you can check out their GitHub repository.

Monday, March 17, 2014

Shrink Your Time Machine Backups and Free Disk Space

Update: In a newer post, I describe a shell script I published to automate Time Machine backup deletion.

Time Machine is a backup and restore tool from Apple which is very well integrated into OS X. In my personal opinion Time Machine is not yet awesome and its shortcomings often force me to use alternative methods when I need to backup files and folders with certain characteristics.

The most important use case in which I strongly discourage anybody to use Time Machine is the backup of frequently updated big files. Time Machine always copies the whole file because it is not able to transfer only the differences between the previous state of a file and the current one. This fact has many detrimental consequences:
  • Backups are slow.
  • Backups may take a huge amount of disk space.
When I say huge, I mean enormous. Think about a virtual machine disk stored as a file in your disk: if just one bit of that file changes (and you can bet it changes every time you use your virtual machine), Time Machine will perform a copy of the whole file the next time a backup is run.

Fortunately, there exist tools which are able to examine a file and transfer only the difference with a previous stored state, such as rsync, on which you can rely to build your custom backup policies.

Anyway, no matter how Time Machine has eaten up a lot of your disk space, it may come a moment when you really need to free some of it, possibly deleting old backups and shrinking a Time Machine sparse bundle disk image.

Deleting Old Backups

Old backups can be deleted in many ways, the simplest one being the following:
  • Open the Time Machine application when the Finder application is in the foreground.
  • Navigate to the backup to be deleted double clicking on the corresponding position of the ruler on the right side of the screen.
  • Right click with the mouse on the empty space in the Finder.
  • Select Delete Backup.
Time Machine will ask you to introduce the super user password and then it will delete the selected backup.

Unfortunately this method is very clumsy if you need to delete many backups.

Another way is using the tmutil command to perform the deletion. Not only it is simpler, but it will allow you to do it programmatically if you need to. To delete a backup using tmutil you must perform the following operations:
  • Make sure your time machine backup disk is mounted (the simplest way to do it is opening the Time Machine application).
  • The format of the backup folders created by Time Machine is YYYY-MM-DD-HHmmss. If you want to delete a specific backup, you can use the following command:
$ sudo tmutil delete /full/path/to/backup/Backups.backupdb/machine/backup-name

Time Machine currently stores its backups in a folder named after the backed up machine, into the Backups.backupdb folder in the backup disk. This means that, if your machine is called iMac and your backup disk is mounted on /Volumes/Time Machine Backups, then backups will be located in the following folder:

/Volumes/Time Machine Backups/Backups.backupdb/iMac

If you want to delete the 2014-02-02-123411 backup, you must run the following command:

$ sudo tmutil delete /Volumes/Time Machine Backups/Backups.backupdb/iMac/2014-02-02-123411

You can easily make a script, for example, to delete all the backups of a specific month. The following commands will delete all the backups created in January 2014 (lines were split with \):

$ sudo bash
Password:
$ for i in /Volumes/Time\ Machine\ Backups/Backups.backupdb/iMac/2014-01* ; \
  do \
    tmutil delete "$i" ; \
  done

Deleting Backups of Any Machine

The same commands can be used to delete backups performed by any machine, not only the machine you are executing them from. This is particularly useful if your time machine backup disk is located on a NAS (such as Apple's Time Capsule).

In this case, though, you will have to mount the disk image file created for every machine and named after it. Time machine creates sparse bundle disk images which can be mounted using the Disk Utility application:
  • Open the Disk Utility application.
  • Choose the File/Open Disk Image... menu item (⌥⌘O).
  • Choose the disk image file corresponding to the backup disk of the machine whose backups you want to delete.
Disk Utility will mount the disk image and you can now use the commands shown above to delete the time machine backups stored in this disk image.

Freeing Space

Now that you are able to delete backups, you may notice that no disk space is relinquished if a sparse bundle disk image is being used as backup disk, which is the default behaviour when the backup disk is not a locally attached physical disk.

In this case, when Time Machine frees disk space, the space is freed inside the disk image, but unless the disk image itself frees it as well, the result is that no space is relinquished outside of it.

Fortunately, unallocated space can be freed from a sparse bundle using the following command (make sure the disk image is not mounted when executing this command):

$ sudo hdiutil compact /path/to/disk-image
Starting to compact…
Reclaiming free space…
.................................................................................................................................................................................................................
Finishing compaction…
Reclaimed 11.2 GB out of 118.7 GB possible.

As you can see, hdiutil reports the space which has been reclaimed and you should now see the specified amount of space as additional free space in the corresponding disk.