?

Log in

No account? Create an account

February 13th, 2009

Mirrored swap with zfs on OpenSolaris

I recently installed OpenSolaris 2008.11 on my development server (highly recommended, btw). Out-of-the-box it installs with zfs root filesystems (a relatively new feature in the Solaris/OpenSolaris world) which makes it much easier to do many administrative tasks, such as taking filesystem snapshots, performing safe upgrades (upgrades are performed on a snapshot/clone of the live root, which can then be booted from; fallback to previous root is the easy backout method); and mirror the root filesystem onto a second disk.

After installing a second disk, mirroring the root filesystem was as easy as a zpool attach command (after partitioning & labelling the disk for Solaris use).

The install didn't, however, configure a swap partition on top of zfs. Just a plain old standard swap slice. Very boring!

Pre-Solaris 10 days I would configure mirrored swap (and root) using Disksuite. In these modern times I wanted to see how difficult it would be to setup a mirrored swap on top of zfs. Not too difficult at all, it turns out. This is how to do it.

Choose a slice that exists on both disks with the same size. In my case, the OpenSolaris install had configured a 2GB slice to use for swap. I disabled swap on that slice with:
$ pfexec swap -d /dev/dsk/c3d1s1

Then create a new mirrored zfs pool across the two disks (if you only have one disk, just create a standard zpool on the one slice):
$ pfexec zpool create -m legacy -f swap mirror c3d0s1 c3d1s1

Specify "-m legacy" to prevent zpool from creating and mounting a zfs filesystem at /swap automatically. We don't want to use this zfs pool for normal filesystems, and "legacy" tells zfs to leave it alone.

Next, create a zfs volume that can be accessed as a block device (like "/dev/{dsk,rdsk}/path"). This type of zfs volume is called a "zvol" and comes with block devices at "/dev/zvol/{dsk,rdsk}/path". It seems that zvols must be created with a fixed size (probably reasonable, given the confusion that growing and shrinking such devices could cause) so we use "-V" to specify the size of the volume. The only gotcha is that the size must be a multiple of the volume block size, so I chose the largest multiple of 512KB below the size of the slice (1.95GB in my case):
$ pfexec zfs create -V 1945600k swap/swap0

We can verify that worked by checking for a block device:
$ ls -l /dev/zvol/dsk/swap/swap0 
lrwxrwxrwx   1 root     root          35 Feb 13 18:48 /dev/zvol/dsk/swap/swap0 -> ../../../../devices/pseudo/zfs@0:2c

Finally, tell Solaris to start using it for swap and we are done:
$ pfexec swap -a /dev/zvol/dsk/swap/swap0
$ swap -l
swapfile                  dev    swaplo   blocks     free
/dev/zvol/dsk/swap/swap0 182,2         8  3891192  3891192

Lastly, check the status of the zfs pool, make sure it is healthy (usually worth doing this sooner!):
$ zpool status swap
  pool: swap
 state: ONLINE
 scrub: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        swap        ONLINE       0     0     0
          mirror    ONLINE       0     0     0
            c3d0s1  ONLINE       0     0     0
            c3d1s1  ONLINE       0     0     0

errors: No known data errors

Update: One last step (that I forgot in the original write-up) is to make the swap setting persistent. This is done with an entry in /etc/vfstab:
/dev/zvol/dsk/swap/swap0        -               -               swap    -       no      -

Make sure to test it with a reboot.