This is just a cheap trick en route to building an arbitrary set of zones in the least possible time. The end result of this walk-through creates new zones in a few keystrokes. Along the way, however, I also create a cheater device pool using space from an existing UFS partition. That's fun too.
Let's do that for starters. You can create a device pool for ZFS by using a form of reserved file space. These objects are zero-filled allocations of disk space set with a sticky bit. They're often used to supplement or replace the paging capacity of a system, like so:
# mkfile 256m /pagespace # ls -l /pagespace -rw------T 1 root root 268435456 May 10 17:08 /pagespace # swap -a /pagespace # swap -l swapfile dev swaplo blocks free /dev/dsk/c0t0d0s1 136,9 16 1052624 1052624 /pagespace - 16 524272 524272
Now the /pagespace file is available for paging along with the dedicated device that was previously installed. It is worth noting however, that because mkfile(1M) zero-fills the space, the time required to make a file scales with its on-disk size:
# ptime mkfile 256m /pagespace1 real 4.687 user 0.044 sys 1.193 # ptime mkfile 1024m /pagespace2 real 20.714 user 0.182 sys 5.626
ZFS, as it turns out, can use these file objects to make a pool. That is, we can emulate disk space for play. What's more, ZFS doesn't require reserved space like the swap system does. Using mkfile -n, we can simply declare the files:
# ptime mkfile -n 2048m /cant_be_page_file_though real 0.045 user 0.001 sys 0.003 # ls -l /cant_be_page_file_though -rw------T 1 root root 2147483648 May 10 17:20 /cant_be_page_file_though # swap -a /cant_be_page_file_though "/cant_be_page_file_though" may contain holes - can't swap on it.
We're only doing this to save time. All who decide to grow such a file beyond physical disk capacity did not learn this trick from me. So long as we're playing nice, however, we can create vdevs very quickly, make a zpool, and pay only for disk space that's actually consumed. This cheat might be handy for creating a demo or test on a system that has little disk room to spare:
# for i in 1 2 3 4 5 6 7 8
> do
> mkfile -n 1024m /vdevs/diskZ${i}
> done
# zpool create zfzones /vdevs/diskZ?
# zpool list
NAME SIZE USED AVAIL CAP HEALTH ALTROOT
zfzones 7.94G 60.5K 7.94G 0% ONLINE -
I'm committed to minimal consumption at all points, so let's also turn on compression:
# zfs set compression=on zfzones
Any file system I create from zfzones will inherit this attribute, feeding my other need to factor out extra steps:
# zfs get compression zfzones NAME PROPERTY VALUE SOURCE zfzones compression on local # zfs create zfzones/zone1 # zfs get compression zfzones/zone1 NAME PROPERTY VALUE SOURCE zfzones/zone1 compression on inherited from zfzones
Now the fun part: building zones from this pool:
# zonecfg -z goldzone
goldzone: No such zone configured
Use 'create' to begin configuring a new zone.
zonecfg:goldzone> create
zonecfg:goldzone> set autoboot=false
zonecfg:goldzone> set zonepath=/zfzones/zone1
zonecfg:goldzone> info
zonepath: /zfzones/zone1
autoboot: false
pool:
inherit-pkg-dir:
dir: /lib
inherit-pkg-dir:
dir: /platform
inherit-pkg-dir:
dir: /sbin
inherit-pkg-dir:
dir: /usr
zonecfg:goldzone> verify;commit;exit
# zoneadm -z goldzone install
...
At this point, we could boot the zone and walk through the interactive sysidcfg program. Or, we could put a proper sysidcfg file in the /etc directory of the local zone, and then boot. Before doing either, however, I'll take a snapshot of the zone. Then I'll clone it to zfzones/zone2:
# zfs snapshot zfzones/zone1@presysid # zfs list NAME USED AVAIL REFER MOUNTPOINT zfzones 33.4M 7.78G 33.3M /zfzones zfzones/zone1 24.5K 7.78G 24.5K /zfzones/zone1 zfzones/zone1@presysid 0 - 24.5K - # zfs clone zfzones/zone1@preid zfzones/zone2 # zfs list NAME USED AVAIL REFER MOUNTPOINT zfzones 33.4M 7.78G 33.3M /zfzones zfzones/zone1 24.5K 7.78G 24.5K /zfzones/zone1 zfzones/zone1@preid 0 - 24.5K - zfzones/zone2 0 7.78G 24.5K /zfzones/zone2
Now it's a matter of copying the zone configuration file /etc/zones/goldzone.xml to, say, silver.xml, and edit the value for zonepath in it. Finally, we can copy the entry for goldzone in /etc/zones/index, and modify the zone's name and path as appropriate. Then delete the last field. Now there are two zones in the same state. If you prepare a sysidcfg file for each zone and place them before booting, creation of subsequent zones takes very little time.
Naturally you can bring a zone up to any point you like, snapshot it, clone it, create the needed zone metadata. The impact on disk space at the outset is zero:
# zpool list zfzones NAME SIZE USED AVAIL CAP HEALTH ALTROOT zfzones 7.94G 33.4M 7.90G 0% ONLINE - # zfs clone zfzones/zone1@preid zfzones/zone3 # zfs clone zfzones/zone1@preid zfzones/zone4 # zfs clone zfzones/zone1@preid zfzones/zone5 # zfs clone zfzones/zone1@preid zfzones/zone6 # zfs clone zfzones/zone1@preid zfzones/zone7 # zfs clone zfzones/zone1@preid zfzones/zone8 # zpool list zfzones NAME SIZE USED AVAIL CAP HEALTH ALTROOT zfzones 7.94G 33.5M 7.90G 0% ONLINE - # zfs list NAME USED AVAIL REFER MOUNTPOINT zfzones 33.5M 7.78G 33.3M /zfzones zfzones/zone1 24.5K 7.78G 24.5K /zfzones/zone1 zfzones/zone1@preid 0 - 24.5K - zfzones/zone2 0 7.78G 24.5K /zfzones/zone2 zfzones/zone3 0 7.78G 24.5K /zfzones/zone3 zfzones/zone4 0 7.78G 24.5K /zfzones/zone4 zfzones/zone5 0 7.78G 24.5K /zfzones/zone5 zfzones/zone6 0 7.78G 24.5K /zfzones/zone6 zfzones/zone7 0 7.78G 24.5K /zfzones/zone7 zfzones/zone8 0 7.78G 24.5K /zfzones/zone8
Not bad for starters. Add in scripting, and the savings in both elapsed time and disk space is considerable.

