Since I see regular corruption and filesystem errors on my HFS+ partitions it seemed time to give ZFS on OS X a try.
Since there are several ZFS implementations for OS X available you can choose the one you feel most confident that will work. Regardless… here is the script I wrote to automate the creation of my zpools with some data safety against bit rot and filesystem corruption (at least more than HFS+ offers).
ZFS Utils for OS X
ZFS Utils for OS X on PyPI
You can install it like this:
pip install zfs-utils-osx
# Or if you don't have pip available
easy_install zfs-utils-osx
Usage:
# zfs.py -h
usage: zfs.py [-h] {zpool} ...
optional arguments:
-h, --help show this help message and exit
Subcommands:
Please specify one of the following subcommands
{zpool}
zpool zpool creation
Zpool create usage:
usage: zfs.py zpool [-h] [-c COUNT] [-s SIZE]
[-t {raidz1,raidz2,raidz3,mirror,raidz}] [-n]
[-m MOUNTPOINT] [-o] [-p PATTERN]
pool_name
positional arguments:
pool_name The name of the pool to create
optional arguments:
-h, --help show this help message and exit
-c COUNT, --count COUNT
The amount of images to use (default: 3)
-s SIZE, --size SIZE The usable size of the zpool in GiB (default: 10GiB)
-t {raidz1,raidz2,raidz3,mirror,raidz}, --type {raidz1,raidz2,raidz3,mirror,raidz}
The zpool type to use (default: raidz)
-n, --no-op, --dry-run
Show what will be done but dont execute
-m MOUNTPOINT, --mountpoint MOUNTPOINT
Where should the disk be mounted (default:
~/%(pool_name)s
-o, --overwrite Overwrite old images if they exist
-p PATTERN, --pattern PATTERN
File name pattern to store the images (default:
%(pool_name)s_%(i)02d)
And the actual creation of an image on my local system:
# zfs.py zpool pool --count 4 --size 15
Creating 4 images named pool_00 of size 5.000000GiB for an effective
size of 15.000000GiB. The disk space used will be 20.000000GiB.
# hdiutil create -size 5g -volname pool_00 -type SPARSE -layout NONE pool_00
# hdiutil attach -nomount pool_00.sparseimage
# hdiutil create -size 5g -volname pool_01 -type SPARSE -layout NONE pool_01
# hdiutil attach -nomount pool_01.sparseimage
# hdiutil create -size 5g -volname pool_02 -type SPARSE -layout NONE pool_02
# hdiutil attach -nomount pool_02.sparseimage
# hdiutil create -size 5g -volname pool_03 -type SPARSE -layout NONE pool_03
# hdiutil attach -nomount pool_03.sparseimage
# sudo zpool create -f -m ~/pool pool raidz /dev/disk14 /dev/disk15 /dev/disk16 /dev/disk17
Zpool import usage:
usage: zfs.py load [-h] [-d IMAGE_DIRECTORY] [-p PREFIX] [--postfix POSTFIX]
[-n]
pool_names [pool_names ...]
positional arguments:
pool_names The name of the pool to import
optional arguments:
-h, --help show this help message and exit
-d IMAGE_DIRECTORY, --image-directory IMAGE_DIRECTORY
File name pattern to store the images (default:
~/zfs/)
-p PREFIX, --prefix PREFIX
File name prefix for the images (default:
%(pool_name)s_)
--postfix POSTFIX File name postfix for the images (default: )
-n, --no-op, --dry-run
Show what will be done but dont execute
Example run:
# zfs.py load pool
# hdiutil attach -nomount /Users/rick/zfs/pool_00.sparseimage
# hdiutil attach -nomount /Users/rick/zfs/pool_01.sparseimage
# hdiutil attach -nomount /Users/rick/zfs/pool_02.sparseimage
# hdiutil attach -nomount /Users/rick/zfs/pool_03.sparseimage
# sudo zpool import pool
And to make it mount automatically during boot (make sure you have sudo zpool
in your sudoers file as passwordless), add this to /Library/LaunchDaemons/wolph.zfs.plist
.
<?xml version="1.0" encoding="UTF-8"?>
< !DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>wolph.zfs</string>
<key>ProgramArguments</key>
<array>
<string>zfs.py</string>
<string>load</string>
<string>pool</string>
</array>
<key>RunAtLoad</key>
<true></true>
</dict>
</plist>
In addition, if you want to speed it up a little with a ram drive. You can create and attach one like this:
The size is decided by the number after ram://
, simply multiply the amount of megabytes you want by 2048 (in this case 4096 * 2048 = 4Gi
of ram)
hdiutil attach -nomount ram://8388608
zpool add -f pool cache /dev/diskX
The X should be replaced with the disk drive you got from the hdiutil command.
Note that using a ram drive as a cache drive is a _very_ bad idea if you have L1ARC available (i.e. all except the current OS X implementation I believe), in that case there is really no point to this as you will be trading really fast memory (L1ARC) for a slower ram drive which will be used slightly differently (L2ARC).

No comments yet.