Apple Time Machine – get back in the Driver’s Seat!

Background

Maybe it is just me again overcomplicating things. Yet I recently noticed that when I went on my VPN, using my IPhone to connect to the Internet, and then OpenVPN, at some point, TimeMachine decided to run a backup. Not the best idea in the world even if you are not on a world-wide flat rate, as it will eat up all your internet bandwidth (and also your data plan and hence pocket money if you’re not on a flat rate.)

Unfortunately, TimeMachine, like so many other of Apple’s products, are created for people who Apple apparently considers too dumb to configure anything about – and hence there’s not so much you can configure using their visual tools. I was having one external (USB) disk as TimeMachine target, and one network attached storage (actually a larger server I’m hosting, exposed through netatalk / AFP).

Now TimeMachine having two targets will just cycle through them. If you happen to be on the go, and just “appear” to be home (using VPN), then, well, see above.

Fortunately I saw that Apple provides for a small command line utility, tmutil, which you can utilize to control TimeMachine better. Yet as I’m a strong believer in Wall’s three fundamental virtues of any great programmer, one of which is laziness, I’m definitely too lazy to remember command line options, type stuff by hand, etc. That’s why I utilized today’s lunch break to come up with a quickly hacked together small Perl script which wraps tmutil (i.e., you can use it as a proxy), which gets you back in the driver’s seat. The File is attached, here’s how it works.

Scenario 0: Getting Help

So once you’ve copied the program somewhere and made it executable, e.g. using chmod 755 tmcontrol, you can call it like ./tmcontrol. If you do that without parameters, it first gives out some help of its own, and then invokes tmutil to show its help screen. The way tmcontrol is written, you don’t actually need to call tmutil directly, it acts as a proxy:

mnott-4:scripts mnott$ tmcontrol 
Usage: tmcontrol add|rm|list [target]
For adding, you need the actual url, such as
/Volumes/My Passport for Mac
or
afp://[email protected]/TimeMachine%20Backup
For deleting, a part of the name or url is sufficient.
For running a backup, use run|start|backup as a shorthand for startbackup.
For stopping a running backup, use stop as a shorthand for stopbackup.
Usage: tmcontrol help <verb>
Usage: tmcontrol version
Usage: tmcontrol enable
Usage: tmcontrol disable
Usage: tmcontrol startbackup [-b | --block] [-r | --rotation] [-d | --destination dest_id]
Usage: tmcontrol stopbackup
Usage: tmcontrol enablelocal
Usage: tmcontrol disablelocal
Usage: tmcontrol snapshot
Usage: tmcontrol delete snapshot_path ...
Usage: tmcontrol restore [-v] src dst
Usage: tmcontrol compare [-a@esmugtdEX] [-D depth] [-I name]
 tmcontrol compare [-a@esmugtdEX] [-D depth] [-I name] snapshot_path
 tmcontrol compare [-a@esmugtdEX] [-D depth] [-I name] path1 path2
Usage: tmcontrol setdestination [-a] mount_point
 tmcontrol setdestination [-ap] afp://user[:pass]@host/share
Usage: tmcontrol removedestination destination_id
Usage: tmcontrol destinationinfo [-X]
Usage: tmcontrol addexclusion [-p] item ...
Usage: tmcontrol removeexclusion [-p] item ...
Usage: tmcontrol isexcluded item ...
Usage: tmcontrol inheritbackup machine_directory
 tmcontrol inheritbackup sparse_bundle
Usage: tmcontrol associatedisk [-a] mount_point volume_backup_directory
Usage: tmcontrol latestbackup
Usage: tmcontrol listbackups
Usage: tmcontrol machinedirectory
Usage: tmcontrol calculatedrift machine_directory
Usage: tmcontrol uniquesize path ...
Use `tmcontrol help <verb>` for more information about a specific verb.

As the last line says, for all those commands you can get more detailed help. If, for example, you want to have some help on tmcontrol startbackup, you can do:

mnott-4:scripts mnott$ tmcontrol help startbackup
Usage: tmcontrol add|rm|list [target]

For adding, you need the actual url, such as

  /Volumes/My Passport for Mac

or

  afp://[email protected]/TimeMachine%20Backup

For deleting, a part of the name or url is sufficient.

For running a backup, use run|start|backup as a shorthand for startbackup.

For stopping a running backup, use stop as a shorthand for stopbackup.

Usage: tmutil startbackup [-b | --block] [-r | --rotation] [-d | --destination dest_id]
Perform a backup. This is similar to choosing "Back Up Now" from the Time Machine menu extra.

OPTIONS:
   --block         Wait (block) until the backup is finished before exiting.
   --rotation      Allow automatic destination rotation during the backup.
   --destination   Perform the backup to the destination corresponding to the specified ID.

 

Scenario 1: Controlling your Backup Targets

Requirement 1: List the Backup Targets

If you want to disable or enable backup targets, something that TimeMachine does not allow you to do on the fly without removing and later re-adding the targets, you first need to know which targets you have. To just list your backup targets, you can do it like this:

mnott-4:scripts mnott$ tmcontrol list
====================================================
Name : My Passport for Mac
Kind : Local
Mount Point : /Volumes/My Passport for Mac
ID : 753F44C1-3C43-4C9A-A905-6A7E56D3D121
> ==================================================
Name : TimeMachine Backup
Kind : Network
URL : afp://[email protected]/TimeMachine%20Backup
Mount Point : /Volumes/TimeMachine Backup
ID : 5BD094C7-7FFE-4984-8BCB-EDB75B6D9538

So what this shows you is that I’ve actually configured two targets; one is an external hard disk (“My Passport”), the other is a network attached storage.

Requirement 2: Remove Backup Targets

Now, assume I’m going on a trip and want to hence remove a target temporarily. Say, I don’t want to have TimeMachine backup my data through a mobile connection, i.e. I want to remove the second target, the “Network” kind of target. This can easily be done like this:

mnott-4:scripts mnott$ sudo tmcontrol rm monster
Removing TimeMachine Backup on afp://[email protected]/TimeMachine%20Backup.
====================================================
Name : My Passport for Mac
Kind : Local
Mount Point : /Volumes/My Passport for Mac
ID : 753F44C1-3C43-4C9A-A905-6A7E56D3D121

As you can see, I removed the target (you need to be super user to do that, which is why I prefixed the command with “sudo”). Once removed, the program will show the list of remaining targets. Now, the I basically said, rm (like remove) “monster” – where you can see from the previous listing of targets that “monster” is part of the URL string of the target – it is the name of my server. So how this actually works is that the script will try to find any target that has whatever you provide, as parameter, in either the name of the target or in the URL, if it is a network attached storage. All of the matching targets are then removed.

Which means, if I want to be more drastic and remove all of the targets, I can do it (in my case) like this:

mnott-4:scripts mnott$ sudo tmcontrol rm m
Removing My Passport for Mac.
Removing TimeMachine Backup on afp://[email protected]/TimeMachine%20Backup.
tmutil: No destinations configured.

Since “m” is both part of “TimeMachine” backup as well as “monster”, both are removed. Notice that the data is still on those targets, they are just basically removed from the list of targets that TimeMachine knows about.

Requirement 3: Add Backup Targets

Now, let’s say we were a bit overly ambitious and have now removed all our targets. For the local drive, which we know (using “mount” on the command line) is mounted to

/Volumes/My Passport for Mac

We can just re-add it using:

mnott-4:scripts mnott$ sudo tmcontrol add "/Volumes/My Passport for Mac"
====================================================
Name : My Passport for Mac
Kind : Local
Mount Point : /Volumes/My Passport for Mac
ID : 0C90134F-B984-449F-AA27-0F9535C5B507

As before, the utility lists the targets after the fact. Now, if we want to add the network attached storage, we do basically the same thing, utilizing the data that we had seen before:

mnott-4:scripts mnott$ sudo tmcontrol add afp://[email protected]/TimeMachine%20Backup
Destination password: 
> ==================================================
Name : My Passport for Mac
Kind : Local
Mount Point : /Volumes/My Passport for Mac
ID : 0C90134F-B984-449F-AA27-0F9535C5B507
====================================================
Name : TimeMachine Backup
Kind : Network
URL : afp://[email protected]/TimeMachine%20Backup
Mount Point : /Volumes/TimeMachine Backup
ID : 59D4D49E-B12E-4EB8-82EA-154C70AC38B3

As you can see, I’ve a password required for the network attached storage, which is what the utility has asked me to input. If you do not want that password dialog (for automation), you can opt for replacing “-ap” by “-a” in the addLocation function in the script and then pass the password on the command line:

 sudo tmcontrol add afp://mnott:[email protected]/TimeMachine%20Backup

But notice that this is probably not such a good idea as your password will be visible to anyone utilizing your computer at the same time through a simple ps -ax process listing (if you’re alone on your machine, then why not).

Scenario 2: Running a Backup

So down to here, I’ve already solved my actual problem. Now since the tmutil program from Apple provides for quite a number of more options, I decided to make some of them more easily accessible. The first of them, of course, is to actually tell TimeMachine to run a backup “right now”:

mnott-4:scripts mnott$ tmcontrol run
mnott-4:scripts mnott$ tmcontrol status
 Latest backups:

 /Volumes/My Passport for Mac/Backups.backupdb/mnott (3)/2013-06-03-090926   
 /Volumes/My Passport for Mac/Backups.backupdb/mnott (3)/2013-06-03-104232
 /Volumes/My Passport for Mac/Backups.backupdb/mnott (3)/2013-06-03-131350
 /Volumes/My Passport for Mac/Backups.backupdb/mnott (3)/2013-06-03-142114
 /Volumes/My Passport for Mac/Backups.backupdb/mnott (3)/2013-06-03-143457
 /Volumes/My Passport for Mac/Backups.backupdb/mnott (3)/2013-06-03-150029
 /Volumes/My Passport for Mac/Backups.backupdb/mnott (3)/2013-06-03-150635
 /Volumes/My Passport for Mac/Backups.backupdb/mnott (3)/2013-06-03-154653
 /Volumes/My Passport for Mac/Backups.backupdb/mnott (3)/2013-06-03-161245
 /Volumes/My Passport for Mac/Backups.backupdb/mnott (3)/2013-06-03-163117
 /Volumes/My Passport for Mac/Backups.backupdb/mnott (3)/2013-06-03-165720
 /Volumes/My Passport for Mac/Backups.backupdb/mnott (3)/2013-06-03-170016
 /Volumes/My Passport for Mac/Backups.backupdb/mnott (3)/2013-06-03-171631
 /Volumes/My Passport for Mac/Backups.backupdb/mnott (3)/2013-06-03-173048

Backup session status:
 {
 BackupPhase = Copying;
 ClientID = "com.apple.backupd";
 DateOfStateChange = "2013-06-03 16:09:18 +0000";
 DestinationID = "6FA99302-E117-4631-8B9C-57CE90B35704";
 DestinationMountPoint = "/Volumes/My Passport for Mac";
 Percent = "0.001512141859494737";
 Progress = {
 TimeRemaining = "-1";
 "_raw_totalBytes" = 14408172;
 bytes = 24208;
 files = 286;
 totalBytes = 15848989;
 totalFiles = 286;
 };
 Running = 1;
 Stopping = 0;
 "_raw_Percent" = "0.001680157621660819";
 }

As you can also see, you can use “tmcontrol status” to find out what’s going on. After a while, the situation should show up as idle:

mnott-4:scripts mnott$ tmcontrol status
Latest backups:

/Volumes/My Passport for Mac/Backups.backupdb/mnott (3)/2013-06-03-090926
/Volumes/My Passport for Mac/Backups.backupdb/mnott (3)/2013-06-03-104232
/Volumes/My Passport for Mac/Backups.backupdb/mnott (3)/2013-06-03-131350
/Volumes/My Passport for Mac/Backups.backupdb/mnott (3)/2013-06-03-142114
/Volumes/My Passport for Mac/Backups.backupdb/mnott (3)/2013-06-03-143457
/Volumes/My Passport for Mac/Backups.backupdb/mnott (3)/2013-06-03-150029
/Volumes/My Passport for Mac/Backups.backupdb/mnott (3)/2013-06-03-150635
/Volumes/My Passport for Mac/Backups.backupdb/mnott (3)/2013-06-03-154653
/Volumes/My Passport for Mac/Backups.backupdb/mnott (3)/2013-06-03-161245
/Volumes/My Passport for Mac/Backups.backupdb/mnott (3)/2013-06-03-163117
/Volumes/My Passport for Mac/Backups.backupdb/mnott (3)/2013-06-03-165720
/Volumes/My Passport for Mac/Backups.backupdb/mnott (3)/2013-06-03-170016
/Volumes/My Passport for Mac/Backups.backupdb/mnott (3)/2013-06-03-171631
/Volumes/My Passport for Mac/Backups.backupdb/mnott (3)/2013-06-03-173048
/Volumes/My Passport for Mac/Backups.backupdb/mnott (3)/2013-06-03-181011

Backup session status:
{
    ClientID = "com.apple.backupd";
    Running = 0;
}

Also, what “tmcontrol status” does is that it gives you a list of your most recent backups.

If you don’t like the word “run”, you can also utilize “start” or “backup” or “startbackup” (which is the default for tmutil.

Scenario 3: Stopping a Backup

If you want to stop a running backup, you’d just use “tmcontrol stop” or also “tmcontrol stopbackup” if that’s what you prefer. You should then use “tmcontrol status” to find out whether your backup has actually been stopped.

What I did notice, though, that sometimes TimeMachine appears to get stuck (think of an overly attached backup drive) – so if you want to clear that up, just “tmcontrol rm” remove all those drives and add them again.

Scenario 4: Becoming even more Productive

Now, that’s of course already pretty awesome. If you want to make even more out of your TimeMachine backups, then I really strongly suggest you check out BackupLoupe. These guys have done an awesome job adding a visual interface on top of TimeMachine which allows you to find stuff, diff stuff, etc. They give it aways for free, but allow you to pay something for supporting them. I just found out about what they do today, and I love it. They don’t do the simple stuff my Perl script does (like removing and attaching  targets and running and stopping backups), but that’s not their mission: They care about giving you a much better, cleaner access to the content of your backups. I was just learning about their tool today when I considered adding a diff like functionality (like, git status, git diff, etc.) but as I saw what they did, there’s no point in doing that again. See virtues.

So, I hope this will help you guys to be more comfortable with your backups. I’ve so far not really utilized TimeMachine as I was constantly, regularly, getting broken backups – it sometimes is sufficient to just close the laptop while a backup to a network attached storage is running. It got better, recently, but not entirely reliable. I’m using my own set of rsync scripts on that, but with these options now, there’s a good motivation to go away from that somehow and invest more in TimeMachine.

Here’s the script (and excuse the verbosity and errors, that was literally hacked together in today’s lunch break):

tmcontrol.zip

Share