HOWTO: Time Machine tweaking: fixing ACLs and extended attributes using fsaclctl and chflags
I recently needed to reinstall OS X on my laptop. Once I reinstalled, I my primary username (”max”) didn’t have the same UID that it had had on the prior install. This didn’t cause any problems until I wanted to browse my Time Machine backups while not as root.
Much to my chagrin, I wasn’t able to change ownership of the old backups of /Users/max with a simple chown -R. What was going on here?
Two things. Volumes configured for Time Machine use two mechanisms to keep users (including you too, root) from mucking around too much and making the backups un-useful.
(It’s actually fairly difficult to corrupt a Time Machine backup, due to its novel and clever use of hardlinks, described at some length in this excellent article by John Siracusa, which I actually mentioned in an earlier post. One of the great things about Time Machine is that the files are actually files, not wrapped in some gargantuan monolithic binary clump comprehensible only to a particular flavor of backup software.)
If you need to do major mucking, like I did, this is what you have to deal with:
- Filesystem ACLs, manipulated with
fsaclctl. (Yeah, it’s a damn mouthful. Think “filesystem ACL control” and you’ll be somewhat OK. - UFS+ extended filesystem attributes, manipulated with
chflags
You might not need to do major mucking. You might want to do parts of this if, for example, you discover that Time Machine just backed up a bunch of Linux ISOs you really don’t want to waste your storage space backing up.
Naturally, you’ll need to be root or using sudo in order to actually change these.
First, you need to disable ACLs on the filesystem being managed by Time Machine. It’s easy. This doesn’t destroy any ACL metadata stored, it just stops (temporarily, if you wish) from being used or enforced.
fsaclctl -p /Volumes/backup_vol -d
where “backup_vol” is whatever the name of your Time Machine volume is.
Next, if you had the same situation as I did where you need to change ownership of a whole branch of your filesystem, you’ll want to use chflags, but probably selectively. Here’s what I did:
find /Volumes/backup_vol/Backups.backupdb/machinename/”Macintosh HD”/Users/max -flags +uchg -print0 | xargs -0 chflags -R nouchg
where machinename is the short hostname of the backed-up machine in question. “Macintosh HD” is the default main volume name, which may or may not be the case for you; don’t forget to enclose the name in quotes if it’s got spaces in it.
For those less Unix-inclined of you, that finds every file in my backed up /Users/max branch that has the “uchg” flag set (no user changes permitted) and unsets the flag. For my purposes, I don’t believe I need to reset the “uchg” flag back, so I didn’t store the changed filenames in order to do so.
Finally I changed the whole branch to belong to me again:
chown -Rh max /Volumes/backup_vol/Backups.backupdb/machinename/”Macintosh HD”/Users/max
There were a couple of symlinks that the above choked on, but they weren’t important enough to me to track down exactly why the ownership of the symlinks wasn’t changing. This may not, obviously, be the case every time. I could have programmatically found them, deleted them, and re-linked them, but it wasn’t worth the effort.
Don’t forget to turn the filesystem ACLs back on:
fsaclctl -p /Volumes/backup_vol -e
/etc/hosts entries on OS X Leopard (10.5.5)
I was having a hell of a time making entries in /etc/hosts in Leopard. I’d never had any issue in Tiger. Without getting into the details of the fairly complicated way that Leopard handles name resolution via DNS, directory services, and flatfiles (you can look elsewhere for that), it appears that Leopard is pretty picky aout where precisely you put entries in /etc/hosts.
A virgin /etc/hosts file looks like this in Leopard:
## # Host Database # # localhost is used to configure the loopback interface # when the system is booting. Do not change this entry. ## 127.0.0.1 localhost 255.255.255.255 broadcasthost ::1 localhost fe80::1%lo0 localhost
I thought it would make sense to put in my new IPv4 entries above the IPv6 entries (i.e., between the broadcasthost line and the ::1 localhost line. Right? Wrong. If you put them there, your resolver will happily go on ignoring them until the end of time.
Put them at the bottom of the file and they’ll work.
Addendum 19 May 2009: I’m reading the O’Reilly book “Mac OS X for Unix geeks,” and here’s how to do it the OS X way:
$ sudo dscl . /Hosts/www.awfultimewastingsite.com ip_address 127.0.0.1
Note that /Hosts/ is not part of the filesystem — it’s part of the Directory Services local database.
The directory entries take precedence over /etc/hosts.
Where to catch up on OS X tech stuff
I’ve long felt much shakier about the OS X internals than I have about Linux or Solaris. It’s not been that clear to me where to turn to get solid OS X technical overviews without getting too distracted by fluff (OS X user sites) or by more detail than I necessarily needed at once (Apple’s OS documentation.)
Enter Ars Technica’s John Siracusa. The breadth he uses to review OS X Leopard (10.5) is amazing — he covers everything from kernel details to user-interface design decisions. The review is here, but he’s got plenty of other excellent articles covering great OS X topics like the Finder, HFS+, and the evolution of OS X file metadata.
Siracusa is one of the best technical writers I’ve read in a long time.
