ZFS within a Zone: Using Datasets

Posted on October 1, 2006

Around B43 Solaris Zones were given a new configuration attribute: dataset. This allows us to provide ZFS within a zone itself.

Before I continue, I think we should talk about ZFS terminology for a second. When I first started out with ZFS I found this idea of nested filesystems a bit odd. I remember watching the flash demo’s created by Dan Price and wondering why he kept creating filesystems within filesystems. When I see /storage/users/benr I think directories, not nested filesystems. But, over time as I’ve used ZFS more and more I’ve learned to adapt my thinking and now see the power and flexability provided. Instead of thinking of nested filesystems we can think of datasets within a pool which provide end-point filesystems. Of course to really see how this works you should sit down and look at the beauty of ZFS’s design (this is a good starting point, or listen to the designers describe in this video). And so for now, a pool is base structure that ties layout to disk, datasets are abstractions that act as a root for other filesystems, and filesystems are what you typically think of for storing data.

Back to the joys of ZFS… If your already using ZFS and Zones you have everything you need, you just need to connect the two. Lets see how.

Lets first take a look at the zone we’re going to modify using zonecfg‘s info option:

root@aeon ~$ zonecfg -z playzone001 info
zonename: playzone001
zonepath: /ultrastor/playzone001
autoboot: true
        dir: /lib
        dir: /platform
        dir: /sbin
        dir: /usr
        physical: nge0

As you can see, nothing special or interesting about it.

Now lets create a ZFS dataset, a filesystem that will host future filesystems within the zone:

root@aeon ~$ zfs create ultrastor/playzone001_ds

That was simple. Now lets give that dataset to the zone to use. We’ll use zonecfg to set the “dataset” resource’s “name” property which points to the dataset we just created. After making config change we’ll need to reboot the zone to make it take effect.

root@aeon ~$ zonecfg -z playzone001 'add dataset; set 
name="ultrastor/playzone001_ds"; end; verify; commit'
root@aeon ~$ zoneadm -z playzone001 reboot

Done! Now lets have a looksie…

root@aeon ~$ zlogin playzone001
[Connected to zone 'playzone001' pts/15]
Last login: Sat Sep 30 02:07:13 on pts/21
Sun Microsystems Inc.   SunOS 5.11      snv_47  October 2007
# zfs list
ultrastor              251G   115G  66.3G  /ultrastor
ultrastor/playzone001_ds  24.5K   115G  24.5K  /ultrastor/playzone001_ds
# df -h
Filesystem             size   used  avail capacity  Mounted on
                       366G    24K   115G     1%    /ultrastor/playzone001_ds

Notice that its already mounted, but the mountpoint is ugly. Lets fix that and create a new filesystem.

# zfs set mountpoint=/zfs ultrastor/playzone001_ds
# df -h
Filesystem             size   used  avail capacity  Mounted on
                       366G    24K   115G     1%    /zfs
# zfs create ultrastor/playzone001_ds/web
# zfs set mountpoint=/web ultrastor/playzone001_ds/web
# df -h /web
Filesystem             size   used  avail capacity  Mounted on
                       366G    24K   115G     1%    /web
# zfs snapshot ultrastor/playzone001_ds/web@snap1    
# zfs list
ultrastor              251G   115G  66.3G  /ultrastor
ultrastor/playzone001_ds  71.5K   115G  24.5K  /zfs
ultrastor/playzone001_ds/web  24.5K   115G  24.5K  /web
ultrastor/playzone001_ds/web@snap1      0      -  24.5K  -

As you can see, using datasets within a zone is easy to do and adds a lot of power to your container deployments.

It should be noted… functionality within a zone isn’t prefect, for instance the pool and dataset isn’t hidden bellow the zone. It’d be nice ultimately to mask that somehow so you just saw “zfs” as the pool for instance. More noteworthy, however, zfs create -V (size) won’t work within the zone, it gets into a weird state where the filesystem is created but the size ignored, and then you can’t destroy it from within the zone, so you have to go back out to the globalzone and fix it there. But, thats pretty minor.