Alternative ZFS layout
I’ve been experimenting with FreeBSD 10.0-CURRENT and an alternative ZFS layout for more than a year. The idea is to have a simple way of switching between boot environments. Thus, you have the opportunity of reverting to a previous boot environment without resorting to snapshots and rollbacks as you would with a sole boot environment. At the same time we avoid using the immediate top-level ZFS filesystem.
Here’s the alternative ZFS layout. It’s inspired by (Open)Solaris and other sources, so it’s certainly not a work entirely of my own.
| Filesystem | Mountpoint |
|---|---|
zroot |
legacy |
zroot/ROOT |
inherited, i.e. legacy |
zroot/ROOT/20130623-r252101 |
inherited, i.e. legacy,mounted as / by the kernel due to the bootfs property |
zroot/home |
/home |
zroot/home/user1 |
inherited, i.e. /home/user1 |
zroot/home/user2 |
inherited, i.e. /home/user2 |
zroot/tmp |
/tmp |
zroot/usr |
inherited, i.e. legacy |
zroot/usr/compat |
inherited, i.e. legacy |
zroot/usr/compat/linux |
/usr/compat/linux |
zroot/usr/local |
/usr/local |
zroot/usr/local/certs |
inherited, i.e. /usr/local/certs |
zroot/usr/local/etc |
inherited, i.e. /usr/local/etc |
zroot/usr/local/etc/namedb |
inherited, i.e. /usr/local/etc/namedb |
zroot/usr/local/pgsql |
inherited, i.e. /usr/local/pgsql |
zroot/usr/local/www |
inherited, i.e. /usr/local/www |
zroot/usr/obj |
/usr/obj |
zroot/usr/ports |
/usr/ports |
zroot/usr/ports/distfiles |
inherited, i.e. /usr/ports/distfiles |
zroot/usr/ports/packages |
inherited, i.e. /usr/ports/packages |
zroot/usr/ports/workdirs |
inherited, i.e. /usr/ports/workdirs |
zroot/usr/src |
/usr/src |
zroot/var |
/var |
zroot/var/backups |
inherited, i.e. /var/backups |
zroot/var/crash |
inherited, i.e. /var/crash |
zroot/var/db |
inherited, i.e. /var/db |
zroot/var/db/mysql |
inherited, i.e. /var/db/mysql |
zroot/var/db/pkg |
inherited, i.e. /var/db/pkg |
zroot/var/db/ports |
inherited, i.e. /var/db/ports |
zroot/var/empty |
inherited, i.e. /var/empty |
zroot/var/log |
inherited, i.e. /var/log |
zroot/var/mail |
inherited, i.e. /var/mail |
zroot/var/named |
inherited, i.e. /var/named |
zroot/var/run |
inherited, i.e. /var/run |
zroot/var/spool |
inherited, i.e. /var/spool |
zroot/var/spool/ftp |
inherited, i.e. /var/spool/ftp |
zroot/var/tmp |
inherited, i.e. /var/tmp |
zroot/var/unbound |
inherited, i.e. /var/unbound |
In the above case the bootfs zpool property would be set to zroot/ROOT/20130623-r252101.
In a real system, /home should probably reside on a separate zpool, as should the filesystems for any database system.
Is it wise to have the Subversion global revision number for the FreeBSD base repository embedded in the name of each boot environment? Which of the following would you prefer?
- A date, as in
20130718? - The Subversion global revision number, as in
r253445? - Both a date and the Subversion global revision number, as in
20130718-r253445? - Both the Subversion global revision number and a date, as in
r253445-20130718? - The Subversion last changed revision number, as in
r253445? - Both a date and the Subversion last changed revision number, as in
20130718-r253445? - Both the Subversion last changed revision number and a date, as in
r253445-20130718? - None of the above?
I have begun appreciating the third option, but maybe it’s even wiser to use the Subversion last changed revision number, i.e. the sixth option.
Upgrading the system would be as follows. Note that zroot/ROOT/yyyymmdd-rxxxxxx represents the current boot environment, while zroot/ROOT/YYYYMMDD-rXXXXXX represents the clone, with zroot/ROOT/yyyymmdd-rxxxxxx@pre-YYYYMMDD-rXXXXXX being its origin.
svn up /usr/srcrm -Rf /usr/obj/*cd /usr/srcmake -j 12 -DNO_CLEAN buildworld buildkernelzfs snapshot zroot/ROOT/yyyymmdd-rxxxxxx@pre-YYYYMMDD-rXXXXXXzfs clone -o mountpoint=/YYYYMMDD \
zroot/ROOT/yyyymmdd-rxxxxxx@pre-YYYYMMDD-rXXXXXX zroot/ROOT/YYYYMMDD-rXXXXXXmake DESTDIR=/YYYYMMDD installworld installkernelzfs inherit mountpoint zroot/ROOT/YYYYMMDD-rXXXXXXzpool set bootfs=zroot/ROOT/YYYYMMDD-rXXXXXX zrootrmdir /YYYYMMDD- Reboot to single user mode.
mergemaster -pmergemaster -Ficd /usr/srcmake delete-oldmake delete-old-libs- Optionally rebuild
sysutils/lsofand/oremulators/virtualbox-ose-additionsto account for changes in the kernel internals. - Optionally promote the new clone to be independent of its origin:
zfs promote zroot/ROOT/YYYYMMDD-rXXXXXX
Note the snapshot used for the clone’s origin has been moved to be a part of the clone, i.e.zroot/ROOT/YYYYMMDD-rXXXXXX@pre-YYYYMMDD-rXXXXXX. The snapshot is still linked to the previous boot environment. - Optionally destroy older boot environments to conserve disk space.
- Optionally destroy the snapshots for the current boot environment, if warranted and possible.
- Optionally update the boot blocks, particularly if you intend to upgrade the zpools and/or filesystems.
- Optionally upgrade the zpools and/or filesystems.
- Reboot to multi user mode.
Should the need for booting an older boot environment arise, say when you are unable to set the bootfs zpool property using the conventional method, you can accomplish this by interrupting the boot loader, typically by hitting the escape key when the boot menu is shown. Use the lszfs poolname command to inspect the available filesystems. Usually, lszfs zroot/ROOT should give an idea of the available boot environments. Change the currdev variable to the desired boot environment:
OK unload OK set currdev="zfs:zroot/ROOT/yyyymmdd-rxxxxxx:" OK load kernel OK load opensolaris OK load zfs OK boot
Ensure you begin the currdev string with zfs: and terminate the string with a colon, :. Note that setting currdev does not change the bootfs zpool property.
Andriy Gapon’s talk entitled “Practical ZFS For A Common FreeBSD User” at KyivBSD, 2012, put me right on track for considering the use of snapshots and clones. Here’s a picture from the session.
After having used the recipe above, I came to realise the boot times keeps increasing. It turns out all the snapshots are being transferred to the newest BE. At some point it just becomes unbearable, and you need to cut through the crap by creating a fresh BE without any attachments to the prior ones. (I really do miss the old behaviour of the zfs promote command.) To ease the migration from the previous BE to the new one, I began using this procedure:
svn up /usr/srcrm -Rf /usr/obj/*cd /usr/srcmake -j 12 -DNO_CLEAN buildworld buildkernelzfs create -o mountpoint=/YYYYMMDD \
zroot/ROOT/YYYYMMDD-rXXXXXXexport DESTDIR=/YYYYMMDDmake installworld installkerneltar cf - /.bash* /.cshrc /.inputrc /.profile /.rnd /.shrc \
/COPYRIGHT /boot/device.hints /boot/loader.conf /boot/modules \
/boot/zfs/zpool.cache /entropy /etc /media /root | \
(cd ${DESTDIR}; tar xvvf -)ln -s usr/compat ${DESTDIR}/compatln -s /usr/local/bin/perl5.16.3 ${DESTDIR}/usr/bin/perlln -s /usr/local/bin/perl5.16.3 ${DESTDIR}/usr/bin/perl5zfs inherit mountpoint zroot/ROOT/YYYYMMDD-rXXXXXXzpool set bootfs=zroot/ROOT/YYYYMMDD-rXXXXXX zrootrmdir /YYYYMMDD- Reboot to single user mode.
mergemaster -pmergemaster -Ficd /usr/srcmake delete-oldmake delete-old-libs- Optionally rebuild
sysutils/lsofand/oremulators/virtualbox-ose-additionsto account for changes in the kernel internals. - Optionally destroy older boot environments to conserve disk space.
- Optionally update the boot blocks, particularly if you intend to upgrade the zpools and/or filesystems.
- Optionally upgrade the zpools and/or filesystems.
- Reboot to multi user mode.
You might need to adjust the paths accumulated by the first tar command in step 8, and the symlinks in steps 9, 10, and 11.
For production systems one should consider naming the zpools using this as a template:
${hostname}_${pool_role}_g${generation_number}
E.g.:
enterprise_zroot_g06 enterprise_zdata_g06 vico_sensor_data_g01 voyager_omega_g01 yamato_rpool_g02 yamato_section_31_g02
This way each zpool is given a unique name and may easily be imported to other systems, including its own successor and possibly even one of its predecessors. This is handy if and when you prepare new (root) pools for an existing system.
Using two pools the layout would become this:
| Filesystem | Mountpoint |
|---|---|
zroot |
legacy |
zroot/ROOT |
inherited, i.e. legacy |
zroot/ROOT/20130623-r252101 |
inherited, i.e. legacy,mounted as / by the kernel due to the bootfs property |
zroot/tmp |
/tmp |
zroot/usr |
inherited, i.e. legacy |
zroot/usr/compat |
inherited, i.e. legacy |
zroot/usr/compat/linux |
/usr/compat/linux |
zroot/usr/local |
/usr/local |
zroot/usr/local/certs |
inherited, i.e. /usr/local/certs |
zroot/usr/local/etc |
inherited, i.e. /usr/local/etc |
zroot/usr/local/etc/namedb |
inherited, i.e. /usr/local/etc/namedb |
zroot/usr/obj |
/usr/obj |
zroot/usr/ports |
/usr/ports |
zroot/usr/ports/distfiles |
inherited, i.e. /usr/ports/distfiles |
zroot/usr/ports/packages |
inherited, i.e. /usr/ports/packages |
zroot/usr/ports/workdirs |
inherited, i.e. /usr/ports/workdirs |
zroot/usr/src |
/usr/src |
zroot/var |
/var |
zroot/var/backups |
inherited, i.e. /var/backups |
zroot/var/crash |
inherited, i.e. /var/crash |
zroot/var/db |
inherited, i.e. /var/db |
zroot/var/db/pkg |
inherited, i.e. /var/db/pkg |
zroot/var/db/ports |
inherited, i.e. /var/db/ports |
zroot/var/empty |
inherited, i.e. /var/empty |
zroot/var/log |
inherited, i.e. /var/log |
zroot/var/mail |
inherited, i.e. /var/mail |
zroot/var/named |
inherited, i.e. /var/named |
zroot/var/run |
inherited, i.e. /var/run |
zroot/var/spool |
inherited, i.e. /var/spool |
zroot/var/tmp |
inherited, i.e. /var/tmp |
zroot/var/unbound |
inherited, i.e. /var/unbound |
zdata |
legacy |
zdata/home |
/home |
zdata/home/user1 |
inherited, i.e. /home/user1 |
zdata/home/user2 |
inherited, i.e. /home/user2 |
zdata/usr |
inherited, i.e. legacy |
zdata/usr/local |
inherited, i.e. legacy |
zdata/usr/local/pgsql |
/usr/local/pgsql |
zdata/usr/local/www |
/usr/local/www |
zdata/var |
inherited, i.e. legacy |
zdata/var/db |
inherited, i.e. legacy |
zdata/var/db/mysql |
/var/db/mysql |
zdata/var/spool |
inherited, i.e. legacy |
zdata/var/spool/ftp |
/var/spool/ftp |
Here’s a shell script to create the ZFS layout:
#!/bin/sh
# Copyright © 2013, Trond Endrestøl <Trond.Endrestol@ximalas.info>
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
if [ -z "${ROOTPOOL}" ]; then
echo "$0: you must set the environment variable ROOTPOOL to the name of your root pool" >/dev/stderr;
echo "$0: e.g. export ROOTPOOL=zroot" >/dev/stderr;
exit 69;
fi
if ! zpool list "${ROOTPOOL}" >/dev/null 2>/dev/null; then
echo "$0: root pool ${ROOTPOOL} does not exist" >/dev/stderr;
echo "$0: try: zpool create -o cachefile=/tmp/zpool.cache -O mountpoint=legacy ${ROOTPOOL} ..." >/dev/stderr;
exit 69;
fi
if [ -z "${DATAPOOL}" ]; then
echo "$0: you must set the environment variable DATAPOOL to the name of your data pool" >/dev/stderr;
echo "$0: e.g. export DATAPOOL=zdata" >/dev/stderr;
echo "$0: your data pool can be the same as your root pool" >/dev/stderr;
echo "$0: e.g. export DATAPOOL=\${ROOTPOOL}" >/dev/stderr;
exit 69;
fi
if [ "${DATAPOOL}" != "${ROOTPOOL}" ]; then
if ! zpool list "${DATAPOOL}" >/dev/null 2>/dev/null; then
echo "$0: data pool ${DATAPOOL} does not exist" >/dev/stderr;
echo "$0: try: zpool create -o cachefile=/tmp/zpool.cache -O mountpoint=legacy ${DATAPOOL} ..." >/dev/stderr;
exit 69;
fi;
fi
if [ -z "${RELEASEDATE}" ]; then
echo "$0: you must set the environment variable RELEASEDATE to the date of the release you are installing" >/dev/stderr;
echo "$0: e.g. export RELEASEDATE=20130602" >/dev/stderr;
exit 69;
fi
if [ -z "${RELEASEREV}" ]; then
echo "$0: you must set the environment variable RELEASEREV to the Subversion revision number of the release you are installing" >/dev/stderr;
echo "$0: e.g. export RELEASEREV=251259" >/dev/stderr;
exit 69;
fi
# It is assumed the pools were created with -O mountpoint=legacy.
zfs create ${ROOTPOOL}/ROOT
zfs create ${ROOTPOOL}/ROOT/${RELEASEDATE}-r${RELEASEREV}
zpool set bootfs=${ROOTPOOL}/ROOT/${RELEASEDATE}-r${RELEASEREV} ${ROOTPOOL}
zfs create ${ROOTPOOL}/tmp
zfs create ${ROOTPOOL}/usr
zfs create ${ROOTPOOL}/usr/compat
zfs create ${ROOTPOOL}/usr/compat/linux
zfs create ${ROOTPOOL}/usr/local
zfs create ${ROOTPOOL}/usr/local/certs
zfs create ${ROOTPOOL}/usr/local/etc
zfs create ${ROOTPOOL}/usr/local/etc/namedb
zfs create ${ROOTPOOL}/usr/obj
zfs create ${ROOTPOOL}/usr/ports
zfs create ${ROOTPOOL}/usr/ports/distfiles
zfs create ${ROOTPOOL}/usr/ports/packages
zfs create ${ROOTPOOL}/usr/ports/workdirs
zfs create ${ROOTPOOL}/usr/src
zfs create ${ROOTPOOL}/var
zfs create ${ROOTPOOL}/var/backups
zfs create ${ROOTPOOL}/var/crash
zfs create ${ROOTPOOL}/var/db
zfs create ${ROOTPOOL}/var/db/pkg
zfs create ${ROOTPOOL}/var/db/ports
zfs create ${ROOTPOOL}/var/empty
zfs create ${ROOTPOOL}/var/log
zfs create ${ROOTPOOL}/var/mail
zfs create ${ROOTPOOL}/var/named
zfs create ${ROOTPOOL}/var/run
zfs create ${ROOTPOOL}/var/spool
zfs create ${ROOTPOOL}/var/tmp
zfs create ${ROOTPOOL}/var/unbound
zfs create ${DATAPOOL}/home
if [ "${DATAPOOL}" != "${ROOTPOOL}" ]; then
zfs create ${DATAPOOL}/usr;
zfs create ${DATAPOOL}/usr/local;
fi
zfs create ${DATAPOOL}/usr/local/pgsql
zfs create ${DATAPOOL}/usr/local/www
if [ "${DATAPOOL}" != "${ROOTPOOL}" ]; then
zfs create ${DATAPOOL}/var;
zfs create ${DATAPOOL}/var/db;
zfs create ${DATAPOOL}/var/spool;
fi
zfs create ${DATAPOOL}/var/db/mysql
zfs create ${DATAPOOL}/var/spool/ftp
zfs set atime=off ${DATAPOOL}/var/spool/ftp;
zfs set compression=gzip-9 ${ROOTPOOL}/tmp
zfs set compression=gzip-9 ${ROOTPOOL}/usr/local/certs
zfs set compression=gzip-9 ${ROOTPOOL}/usr/local/etc
zfs set compression=gzip-9 ${DATAPOOL}/usr/local/www
zfs set compression=gzip-9 ${ROOTPOOL}/usr/ports
zfs set compression=gzip-9 ${ROOTPOOL}/usr/src
zfs set compression=gzip-9 ${ROOTPOOL}/var/db/pkg
zfs set compression=gzip-9 ${ROOTPOOL}/var/db/ports
zfs set compression=gzip-9 ${ROOTPOOL}/var/log
zfs set compression=gzip-9 ${ROOTPOOL}/var/mail
zfs set compression=gzip-9 ${ROOTPOOL}/var/named
zfs set compression=gzip-9 ${ROOTPOOL}/var/tmp
zfs set compression=gzip-9 ${ROOTPOOL}/var/unbound
zfs set compression=off ${ROOTPOOL}/usr/ports/distfiles
zfs set compression=off ${ROOTPOOL}/usr/ports/packages
zfs set compression=off ${ROOTPOOL}/usr/ports/workdirs
zfs set exec=off ${ROOTPOOL}/usr/local/etc/namedb
zfs set exec=off ${ROOTPOOL}/usr/ports/distfiles
zfs set exec=off ${ROOTPOOL}/usr/ports/packages
zfs set exec=off ${ROOTPOOL}/usr/src
zfs set exec=off ${ROOTPOOL}/var/backups
zfs set exec=off ${ROOTPOOL}/var/crash
zfs set exec=off ${ROOTPOOL}/var/db
zfs set exec=off ${ROOTPOOL}/var/empty
zfs set exec=off ${ROOTPOOL}/var/log
zfs set exec=off ${ROOTPOOL}/var/mail
zfs set exec=off ${ROOTPOOL}/var/named
zfs set exec=off ${ROOTPOOL}/var/run
zfs set exec=off ${ROOTPOOL}/var/spool
zfs set exec=off ${ROOTPOOL}/var/unbound
if [ "${DATAPOOL}" != "${ROOTPOOL}" ]; then
zfs set exec=off ${DATAPOOL}/var/spool;
fi
zfs set exec=on ${ROOTPOOL}/var/db/pkg
zfs set exec=on ${ROOTPOOL}/var/db/ports
zfs set setuid=off ${ROOTPOOL}/tmp
zfs set setuid=off ${DATAPOOL}/home
zfs set setuid=off ${ROOTPOOL}/usr/local/etc/namedb
zfs set setuid=off ${ROOTPOOL}/usr/ports
zfs set setuid=off ${ROOTPOOL}/usr/src
zfs set setuid=off ${ROOTPOOL}/var/backups
zfs set setuid=off ${ROOTPOOL}/var/crash
zfs set setuid=off ${ROOTPOOL}/var/db
zfs set setuid=off ${ROOTPOOL}/var/empty
zfs set setuid=off ${ROOTPOOL}/var/log
zfs set setuid=off ${ROOTPOOL}/var/mail
zfs set setuid=off ${ROOTPOOL}/var/named
zfs set setuid=off ${ROOTPOOL}/var/run
zfs set setuid=off ${ROOTPOOL}/var/spool
zfs set setuid=off ${DATAPOOL}/var/spool
zfs set setuid=off ${ROOTPOOL}/var/tmp
zfs set setuid=off ${ROOTPOOL}/var/unbound
zfs set recordsize=8K ${DATAPOOL}/usr/local/pgsql
zfs set recordsize=16K ${DATAPOOL}/var/db/mysql
Here’s a script for setting the temporary mountpoints rooted at ${DESTDIR}:
#!/bin/sh
# Copyright © 2013, Trond Endrestøl <Trond.Endrestol@ximalas.info>
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
if [ -z "${ROOTPOOL}" ]; then
echo "$0: you must set the environment variable ROOTPOOL to the name of your root pool" >/dev/stderr;
echo "$0: e.g. export ROOTPOOL=zroot" >/dev/stderr;
exit 69;
fi
if ! zpool list "${ROOTPOOL}" >/dev/null 2>/dev/null; then
echo "$0: root pool ${ROOTPOOL} does not exist" >/dev/stderr;
echo "$0: try: zpool create -o cachefile=/tmp/zpool.cache -O mountpoint=legacy ${ROOTPOOL} ..." >/dev/stderr;
exit 69;
fi
if [ -z "${DATAPOOL}" ]; then
echo "$0: you must set the environment variable DATAPOOL to the name of your data pool" >/dev/stderr;
echo "$0: e.g. export DATAPOOL=zdata" >/dev/stderr;
echo "$0: your data pool can be the same as your root pool" >/dev/stderr;
echo "$0: e.g. export DATAPOOL=\${ROOTPOOL}" >/dev/stderr;
exit 69;
fi
if [ "${DATAPOOL}" != "${ROOTPOOL}" ]; then
if ! zpool list "${DATAPOOL}" >/dev/null 2>/dev/null; then
echo "$0: data pool ${DATAPOOL} does not exist" >/dev/stderr;
echo "$0: try: zpool create -o cachefile=/tmp/zpool.cache -O mountpoint=legacy ${DATAPOOL} ..." >/dev/stderr;
exit 69;
fi;
fi
if [ -z "${RELEASEDATE}" ]; then
echo "$0: you must set the environment variable RELEASEDATE to the date of the release you are installing" >/dev/stderr;
echo "$0: e.g. export RELEASEDATE=20130602" >/dev/stderr;
exit 69;
fi
if [ -z "${RELEASEREV}" ]; then
echo "$0: you must set the environment variable RELEASEREV to the Subversion revision number of the release you are installing" >/dev/stderr;
echo "$0: e.g. export RELEASEREV=251259" >/dev/stderr;
exit 69;
fi
if [ -z "${DESTDIR}" ]; then
echo "$0: you must set the environment variable DESTDIR to the destination directory" >/dev/stderr;
echo "$0: e.g. export DESTDIR=/tmp/zroot" >/dev/stderr;
exit 69;
fi
if [ ! -d "${DESTDIR}" ]; then
mkdir -p "${DESTDIR}";
if [ ! -d "${DESTDIR}" ]; then
echo "$0: unable to create destination directory ${DESTDIR}" >/dev/stderr;
exit 69;
fi;
fi
cd /
zfs set mountpoint=${DESTDIR} ${ROOTPOOL}/ROOT/${RELEASEDATE}-r${RELEASEREV}
zfs set mountpoint=${DESTDIR}/home ${DATAPOOL}/home
zfs set mountpoint=${DESTDIR}/tmp ${ROOTPOOL}/tmp
zfs set mountpoint=${DESTDIR}/usr/compat/linux ${ROOTPOOL}/usr/compat/linux
zfs set mountpoint=${DESTDIR}/usr/local ${ROOTPOOL}/usr/local
zfs set mountpoint=${DESTDIR}/usr/obj ${ROOTPOOL}/usr/obj
zfs set mountpoint=${DESTDIR}/usr/ports ${ROOTPOOL}/usr/ports
zfs set mountpoint=${DESTDIR}/usr/src ${ROOTPOOL}/usr/src
zfs set mountpoint=${DESTDIR}/var ${ROOTPOOL}/var
if [ "${DATAPOOL}" != "${ROOTPOOL}" ]; then
zfs set mountpoint=${DESTDIR}/usr/local/pgsql ${DATAPOOL}/usr/local/pgsql;
zfs set mountpoint=${DESTDIR}/usr/local/www ${DATAPOOL}/usr/local/www;
zfs set mountpoint=${DESTDIR}/var/db/mysql ${DATAPOOL}/var/db/mysql;
zfs set mountpoint=${DESTDIR}/var/spool/ftp ${DATAPOOL}/var/spool/ftp;
fi
mkdir ${DESTDIR}/proc
mkdir ${DESTDIR}/usr/compat/linux/proc
chmod 1777 ${DESTDIR}/tmp
chmod 1777 ${DESTDIR}/var/tmp
mkdir ${DESTDIR}/media
mkdir ${DESTDIR}/media/cdrom
mkdir ${DESTDIR}/media/dvdrom
ln -s usr/compat ${DESTDIR}/compat
Pick one of these two shell scripts to extract a base system into ${DESTDIR}:
#!/bin/sh
# Copyright © 2013, Trond Endrestøl <Trond.Endrestol@ximalas.info>
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
if [ -z "${DESTDIR}" ]; then
echo "$0: you must set the environment variable DESTDIR to the destination directory" >/dev/stderr;
echo "$0: e.g. export DESTDIR=/tmp/zroot" >/dev/stderr;
exit 69;
fi
if [ ! -d "${DESTDIR}" ]; then
echo "$0: destination directory ${DESTDIR} does not exist" >/dev/stderr;
echo "$0: maybe mkdir -p ${DESTDIR} needs to be run" >/dev/stderr;
exit 69;
fi
if ! zfs get mountpoint "${DESTDIR}" >/dev/null 2>/dev/null; then
echo "$0: destination directory ${DESTDIR} is not a ZFS filesystem" >/dev/stderr;
exit 69;
fi
cd /dist/8.*/base
echo "$0: Please answer y to the following question!"
./install.sh
# Answer y
cd ../games
./install.sh
cd ../info
./install.sh
cd ../lib32 && ./install.sh
cd ../manpages
./install.sh
cd ../kernels
./install.sh generic
cd ${DESTDIR}/boot
rmdir kernel
mv GENERIC kernel
#!/bin/sh
# Copyright © 2013, Trond Endrestøl <Trond.Endrestol@ximalas.info>
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
if [ -z "${DESTDIR}" ]; then
echo "$0: you must set the environment variable DESTDIR to the destination directory" >/dev/stderr;
echo "$0: e.g. export DESTDIR=/tmp/zroot" >/dev/stderr;
exit 69;
fi
if [ ! -d "${DESTDIR}" ]; then
echo "$0: destination directory ${DESTDIR} does not exist" >/dev/stderr;
echo "$0: maybe mkdir -p ${DESTDIR} needs to be run" >/dev/stderr;
exit 69;
fi
if ! zfs get mountpoint "${DESTDIR}" >/dev/null 2>/dev/null; then
echo "$0: destination directory ${DESTDIR} is not a ZFS filesystem" >/dev/stderr;
exit 69;
fi
cd ${DESTDIR}
tar xvvf /usr/freebsd-dist/kernel.txz
tar xvvf /usr/freebsd-dist/base.txz
tar xvvf /usr/freebsd-dist/lib32.txz
tar xvvf /usr/freebsd-dist/doc.txz
tar xvvf /usr/freebsd-dist/games.txz
Here’s a script for setting the final mountpoints:
#!/bin/sh
# Copyright © 2013, Trond Endrestøl <Trond.Endrestol@ximalas.info>
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
if [ -z "${ROOTPOOL}" ]; then
echo "$0: you must set the environment variable ROOTPOOL to the name of your root pool" >/dev/stderr;
echo "$0: e.g. export ROOTPOOL=zroot" >/dev/stderr;
exit 69;
fi
if ! zpool list "${ROOTPOOL}" >/dev/null 2>/dev/null; then
echo "$0: root pool ${ROOTPOOL} does not exist" >/dev/stderr;
echo "$0: try: zpool create -o cachefile=/tmp/zpool.cache -O mountpoint=legacy ${ROOTPOOL} ..." >/dev/stderr;
exit 69;
fi
if [ -z "${DATAPOOL}" ]; then
echo "$0: you must set the environment variable DATAPOOL to the name of your data pool" >/dev/stderr;
echo "$0: e.g. export DATAPOOL=zdata" >/dev/stderr;
echo "$0: your data pool can be the same as your root pool" >/dev/stderr;
echo "$0: e.g. export DATAPOOL=\${ROOTPOOL}" >/dev/stderr;
exit 69;
fi
if [ "${DATAPOOL}" != "${ROOTPOOL}" ]; then
if ! zpool list "${DATAPOOL}" >/dev/null 2>/dev/null; then
echo "$0: data pool ${DATAPOOL} does not exist" >/dev/stderr;
echo "$0: try: zpool create -o cachefile=/tmp/zpool.cache -O mountpoint=legacy ${DATAPOOL} ..." >/dev/stderr;
exit 69;
fi;
fi
if [ -z "${RELEASEDATE}" ]; then
echo "$0: you must set the environment variable RELEASEDATE to the date of the release you are installing" >/dev/stderr;
echo "$0: e.g. export RELEASEDATE=20130602" >/dev/stderr;
exit 69;
fi
if [ -z "${RELEASEREV}" ]; then
echo "$0: you must set the environment variable RELEASEREV to the Subversion revision number of the release you are installing" >/dev/stderr;
echo "$0: e.g. export RELEASEREV=251259" >/dev/stderr;
exit 69;
fi
cd /
zfs set readonly=on ${ROOTPOOL}/var/empty
zfs unmount -a
zfs inherit mountpoint ${ROOTPOOL}/ROOT/${RELEASEDATE}-r${RELEASEREV}
zfs set mountpoint=/home ${DATAPOOL}/home
zfs set mountpoint=/tmp ${ROOTPOOL}/tmp
zfs set mountpoint=/usr/compat/linux ${ROOTPOOL}/usr/compat/linux
zfs set mountpoint=/usr/local ${ROOTPOOL}/usr/local
zfs set mountpoint=/usr/obj ${ROOTPOOL}/usr/obj
zfs set mountpoint=/usr/ports ${ROOTPOOL}/usr/ports
zfs set mountpoint=/usr/src ${ROOTPOOL}/usr/src
zfs set mountpoint=/var ${ROOTPOOL}/var
if [ "${DATAPOOL}" != "${ROOTPOOL}" ]; then
zfs set mountpoint=/usr/local/pgsql ${DATAPOOL}/usr/local/pgsql;
zfs set mountpoint=/usr/local/www ${DATAPOOL}/usr/local/www;
zfs set mountpoint=/var/db/mysql ${DATAPOOL}/var/db/mysql;
zfs set mountpoint=/var/spool/ftp ${DATAPOOL}/var/spool/ftp;
fi
zfs unmount -a
The five shell scripts are available at this URL: http://ximalas.info/~trond/create-zfs/.
Shell scripts with some canmount=off experiments are available at this URL: http://ximalas.info/~trond/create-zfs/canmount/.
| Filesystem | Mountpoint | canmount |
|---|---|---|
zroot |
legacy |
on |
zroot/ROOT |
inherited, i.e. legacy |
on |
zroot/ROOT/20130623-r252101 |
inherited, i.e. legacy,mounted as / by the kernel due to the bootfs property |
on |
zroot/do-not-destroy |
inherited, i.e. legacy |
on |
zroot/media |
/media |
on |
zroot/nfs |
/nfs |
on |
zroot/tmp |
/tmp |
on |
zroot/usr |
/usr |
off |
zroot/usr/compat |
inherited, i.e. /usr/compat |
on |
zroot/usr/compat/linux |
inherited, i.e. /usr/compat/linux |
on |
zroot/usr/local |
inherited, i.e. /usr/local |
on |
zroot/usr/local/certs |
inherited, i.e. /usr/local/certs |
on |
zroot/usr/local/etc |
inherited, i.e. /usr/local/etc |
on |
zroot/usr/local/etc/namedb |
inherited, i.e. /usr/local/etc/namedb |
on |
zroot/usr/obj |
inherited, i.e. /usr/obj |
on |
zroot/usr/ports |
inherited, i.e. /usr/ports |
on |
zroot/usr/ports/distfiles |
inherited, i.e. /usr/ports/distfiles |
on |
zroot/usr/ports/local |
inherited, i.e. /usr/ports/local |
on |
zroot/usr/ports/packages |
inherited, i.e. /usr/ports/packages |
on |
zroot/usr/ports/workdirs |
inherited, i.e. /usr/ports/workdirs |
on |
zroot/usr/src |
inherited, i.e. /usr/src |
on |
zroot/var |
/var |
on |
zroot/var/backups |
inherited, i.e. /var/backups |
on |
zroot/var/crash |
inherited, i.e. /var/crash |
on |
zroot/var/db |
inherited, i.e. /var/db |
on |
zroot/var/db/pkg |
inherited, i.e. /var/db/pkg |
on |
zroot/var/db/ports |
inherited, i.e. /var/db/ports |
on |
zroot/var/empty |
inherited, i.e. /var/empty |
on |
zroot/var/log |
inherited, i.e. /var/log |
on |
zroot/var/mail |
inherited, i.e. /var/mail |
on |
zroot/var/named |
inherited, i.e. /var/named |
on |
zroot/var/run |
inherited, i.e. /var/run |
on |
zroot/var/spool |
inherited, i.e. /var/spool |
on |
zroot/var/tmp |
inherited, i.e. /var/tmp |
on |
zroot/var/unbound |
inherited, i.e. /var/unbound |
on |
zdata |
legacy |
on |
zdata/do-not-destroy |
inherited, i.e. legacy |
on |
zdata/home |
/home |
on |
zdata/home/user1 |
inherited, i.e. /home/user1 |
on |
zdata/home/user2 |
inherited, i.e. /home/user2 |
on |
zdata/usr |
/usr |
off |
zdata/usr/local |
inherited, i.e. /usr/local |
off |
zdata/usr/local/pgsql |
inherited, i.e. /usr/local/pgsql |
on |
zdata/usr/local/www |
inherited, i.e. /usr/local/www |
on |
zdata/var |
/var |
off |
zdata/var/db |
inherited, i.e. /var/db |
off |
zdata/var/db/mysql |
inherited, i.e. /var/db/mysql |
on |
zdata/var/spool |
inherited, i.e. /var/spool |
off |
zdata/var/spool/ftp |
inherited, i.e. /var/spool/ftp |
on |
Here’s a shell script to create the ZFS layout:
#!/bin/sh
# Copyright © 2013, Trond Endrestøl <Trond.Endrestol@ximalas.info>
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
if [ -z "${ROOTPOOL}" ]; then
echo "$0: you must set the environment variable ROOTPOOL to the name of your root pool" >/dev/stderr;
echo "$0: e.g. export ROOTPOOL=zroot" >/dev/stderr;
exit 69;
fi
if ! zpool list "${ROOTPOOL}" >/dev/null 2>/dev/null; then
echo "$0: root pool ${ROOTPOOL} does not exist" >/dev/stderr;
echo "$0: try: zpool create -o cachefile=/tmp/zpool.cache -O mountpoint=legacy ${ROOTPOOL} ..." >/dev/stderr;
exit 69;
fi
if [ -z "${DATAPOOL}" ]; then
echo "$0: you must set the environment variable DATAPOOL to the name of your data pool" >/dev/stderr;
echo "$0: e.g. export DATAPOOL=zdata" >/dev/stderr;
echo "$0: your data pool can be the same as your root pool" >/dev/stderr;
echo "$0: e.g. export DATAPOOL=\${ROOTPOOL}" >/dev/stderr;
exit 69;
fi
if [ "${DATAPOOL}" != "${ROOTPOOL}" ]; then
if ! zpool list "${DATAPOOL}" >/dev/null 2>/dev/null; then
echo "$0: data pool ${DATAPOOL} does not exist" >/dev/stderr;
echo "$0: try: zpool create -o cachefile=/tmp/zpool.cache -O mountpoint=legacy ${DATAPOOL} ..." >/dev/stderr;
exit 69;
fi;
fi
if [ -z "${RELEASEDATE}" ]; then
echo "$0: you must set the environment variable RELEASEDATE to the date of the release you are installing" >/dev/stderr;
echo "$0: e.g. export RELEASEDATE=20130602" >/dev/stderr;
exit 69;
fi
if [ -z "${RELEASEREV}" ]; then
echo "$0: you must set the environment variable RELEASEREV to the Subversion revision number of the release you are installing" >/dev/stderr;
echo "$0: e.g. export RELEASEREV=251259" >/dev/stderr;
exit 69;
fi
# It is assumed the pools were created with -O mountpoint=legacy.
zfs create ${ROOTPOOL}/do-not-destroy
zfs set reservation=1G ${ROOTPOOL}/do-not-destroy
if [ "${DATAPOOL}" != "${ROOTPOOL}" ]; then
zfs create ${DATAPOOL}/do-not-destroy;
zfs set reservation=1G ${DATAPOOL}/do-not-destroy;
fi
zfs create ${ROOTPOOL}/ROOT
zfs create ${ROOTPOOL}/ROOT/${RELEASEDATE}-r${RELEASEREV}
zpool set bootfs=${ROOTPOOL}/ROOT/${RELEASEDATE}-r${RELEASEREV} ${ROOTPOOL}
zfs create ${ROOTPOOL}/media
zfs create ${ROOTPOOL}/nfs
zfs create ${ROOTPOOL}/tmp
zfs create ${ROOTPOOL}/usr
zfs set canmount=off ${ROOTPOOL}/usr
zfs create ${ROOTPOOL}/usr/compat
zfs create ${ROOTPOOL}/usr/compat/linux
zfs create ${ROOTPOOL}/usr/local
zfs create ${ROOTPOOL}/usr/local/certs
zfs create ${ROOTPOOL}/usr/local/etc
zfs create ${ROOTPOOL}/usr/local/etc/namedb
zfs create ${ROOTPOOL}/usr/obj
zfs create ${ROOTPOOL}/usr/ports
zfs create ${ROOTPOOL}/usr/ports/distfiles
zfs create ${ROOTPOOL}/usr/ports/local
zfs create ${ROOTPOOL}/usr/ports/packages
zfs create ${ROOTPOOL}/usr/ports/workdirs
zfs create ${ROOTPOOL}/usr/src
zfs create ${ROOTPOOL}/var
zfs create ${ROOTPOOL}/var/backups
zfs create ${ROOTPOOL}/var/crash
zfs create ${ROOTPOOL}/var/db
zfs create ${ROOTPOOL}/var/db/pkg
zfs create ${ROOTPOOL}/var/db/ports
zfs create ${ROOTPOOL}/var/empty
zfs create ${ROOTPOOL}/var/log
zfs create ${ROOTPOOL}/var/mail
zfs create ${ROOTPOOL}/var/named
zfs create ${ROOTPOOL}/var/run
zfs create ${ROOTPOOL}/var/spool
zfs create ${ROOTPOOL}/var/tmp
zfs create ${ROOTPOOL}/var/unbound
zfs create ${DATAPOOL}/home
if [ "${DATAPOOL}" != "${ROOTPOOL}" ]; then
zfs create ${DATAPOOL}/usr;
zfs set canmount=off ${DATAPOOL}/usr;
zfs create ${DATAPOOL}/usr/local;
zfs set canmount=off ${DATAPOOL}/usr/local;
fi
zfs create ${DATAPOOL}/usr/local/pgsql
zfs create ${DATAPOOL}/usr/local/www
if [ "${DATAPOOL}" != "${ROOTPOOL}" ]; then
zfs create ${DATAPOOL}/var;
zfs set canmount=off ${DATAPOOL}/var;
zfs create ${DATAPOOL}/var/db;
zfs set canmount=off ${DATAPOOL}/var/db;
zfs create ${DATAPOOL}/var/spool;
zfs set canmount=off ${DATAPOOL}/var/spool;
fi
zfs create ${DATAPOOL}/var/db/mysql
zfs create ${DATAPOOL}/var/spool/ftp
zfs set atime=off ${DATAPOOL}/var/spool/ftp;
zfs set compression=gzip-9 ${ROOTPOOL}/tmp
zfs set compression=gzip-9 ${ROOTPOOL}/usr/local/certs
zfs set compression=gzip-9 ${ROOTPOOL}/usr/local/etc
zfs set compression=gzip-9 ${DATAPOOL}/usr/local/www
zfs set compression=gzip-9 ${ROOTPOOL}/usr/ports
zfs set compression=gzip-9 ${ROOTPOOL}/usr/src
zfs set compression=gzip-9 ${ROOTPOOL}/var/db/pkg
zfs set compression=gzip-9 ${ROOTPOOL}/var/db/ports
zfs set compression=gzip-9 ${ROOTPOOL}/var/log
zfs set compression=gzip-9 ${ROOTPOOL}/var/mail
zfs set compression=gzip-9 ${ROOTPOOL}/var/named
zfs set compression=gzip-9 ${ROOTPOOL}/var/tmp
zfs set compression=gzip-9 ${ROOTPOOL}/var/unbound
zfs set compression=off ${ROOTPOOL}/usr/ports/distfiles
zfs set compression=off ${ROOTPOOL}/usr/ports/packages
zfs set compression=off ${ROOTPOOL}/usr/ports/workdirs
zfs set exec=off ${ROOTPOOL}/usr/local/etc/namedb
zfs set exec=off ${ROOTPOOL}/usr/ports/distfiles
zfs set exec=off ${ROOTPOOL}/usr/ports/packages
zfs set exec=off ${ROOTPOOL}/usr/src
zfs set exec=off ${ROOTPOOL}/var/backups
zfs set exec=off ${ROOTPOOL}/var/crash
zfs set exec=off ${ROOTPOOL}/var/db
zfs set exec=off ${ROOTPOOL}/var/empty
zfs set exec=off ${ROOTPOOL}/var/log
zfs set exec=off ${ROOTPOOL}/var/mail
zfs set exec=off ${ROOTPOOL}/var/named
zfs set exec=off ${ROOTPOOL}/var/run
zfs set exec=off ${ROOTPOOL}/var/spool
zfs set exec=off ${ROOTPOOL}/var/unbound
if [ "${DATAPOOL}" != "${ROOTPOOL}" ]; then
zfs set exec=off ${DATAPOOL}/var/spool;
fi
zfs set exec=on ${ROOTPOOL}/var/db/pkg
zfs set exec=on ${ROOTPOOL}/var/db/ports
zfs set setuid=off ${ROOTPOOL}/tmp
zfs set setuid=off ${DATAPOOL}/home
zfs set setuid=off ${ROOTPOOL}/usr/local/etc/namedb
zfs set setuid=off ${ROOTPOOL}/usr/ports
zfs set setuid=off ${ROOTPOOL}/usr/src
zfs set setuid=off ${ROOTPOOL}/var/backups
zfs set setuid=off ${ROOTPOOL}/var/crash
zfs set setuid=off ${ROOTPOOL}/var/db
zfs set setuid=off ${ROOTPOOL}/var/empty
zfs set setuid=off ${ROOTPOOL}/var/log
zfs set setuid=off ${ROOTPOOL}/var/mail
zfs set setuid=off ${ROOTPOOL}/var/named
zfs set setuid=off ${ROOTPOOL}/var/run
zfs set setuid=off ${ROOTPOOL}/var/spool
zfs set setuid=off ${ROOTPOOL}/var/tmp
zfs set setuid=off ${ROOTPOOL}/var/unbound
if [ "${DATAPOOL}" != "${ROOTPOOL}" ]; then
zfs set setuid=off ${DATAPOOL}/var/spool;
fi
zfs set recordsize=8K ${DATAPOOL}/usr/local/pgsql
zfs set recordsize=16K ${DATAPOOL}/var/db/mysql
Here’s a script for setting the temporary mountpoints rooted at ${DESTDIR}:
#!/bin/sh
# Copyright © 2013, Trond Endrestøl <Trond.Endrestol@ximalas.info>
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
if [ -z "${ROOTPOOL}" ]; then
echo "$0: you must set the environment variable ROOTPOOL to the name of your root pool" >/dev/stderr;
echo "$0: e.g. export ROOTPOOL=zroot" >/dev/stderr;
exit 69;
fi
if ! zpool list "${ROOTPOOL}" >/dev/null 2>/dev/null; then
echo "$0: root pool ${ROOTPOOL} does not exist" >/dev/stderr;
echo "$0: try: zpool create -o cachefile=/tmp/zpool.cache -O mountpoint=legacy ${ROOTPOOL} ..." >/dev/stderr;
exit 69;
fi
if [ -z "${DATAPOOL}" ]; then
echo "$0: you must set the environment variable DATAPOOL to the name of your data pool" >/dev/stderr;
echo "$0: e.g. export DATAPOOL=zdata" >/dev/stderr;
echo "$0: your data pool can be the same as your root pool" >/dev/stderr;
echo "$0: e.g. export DATAPOOL=\${ROOTPOOL}" >/dev/stderr;
exit 69;
fi
if [ "${DATAPOOL}" != "${ROOTPOOL}" ]; then
if ! zpool list "${DATAPOOL}" >/dev/null 2>/dev/null; then
echo "$0: data pool ${DATAPOOL} does not exist" >/dev/stderr;
echo "$0: try: zpool create -o cachefile=/tmp/zpool.cache -O mountpoint=legacy ${DATAPOOL} ..." >/dev/stderr;
exit 69;
fi;
fi
if [ -z "${RELEASEDATE}" ]; then
echo "$0: you must set the environment variable RELEASEDATE to the date of the release you are installing" >/dev/stderr;
echo "$0: e.g. export RELEASEDATE=20130602" >/dev/stderr;
exit 69;
fi
if [ -z "${RELEASEREV}" ]; then
echo "$0: you must set the environment variable RELEASEREV to the Subversion revision number of the release you are installing" >/dev/stderr;
echo "$0: e.g. export RELEASEREV=251259" >/dev/stderr;
exit 69;
fi
if [ -z "${DESTDIR}" ]; then
echo "$0: you must set the environment variable DESTDIR to the destination directory" >/dev/stderr;
echo "$0: e.g. export DESTDIR=/tmp/zroot" >/dev/stderr;
exit 69;
fi
if [ ! -d "${DESTDIR}" ]; then
mkdir -p "${DESTDIR}";
if [ ! -d "${DESTDIR}" ]; then
echo "$0: unable to create destination directory ${DESTDIR}" >/dev/stderr;
exit 69;
fi;
fi
cd /
zfs set mountpoint=${DESTDIR} ${ROOTPOOL}/ROOT/${RELEASEDATE}-r${RELEASEREV}
zfs set mountpoint=${DESTDIR}/home ${DATAPOOL}/home
zfs set mountpoint=${DESTDIR}/media ${ROOTPOOL}/media
zfs set mountpoint=${DESTDIR}/nfs ${ROOTPOOL}/nfs
zfs set mountpoint=${DESTDIR}/tmp ${ROOTPOOL}/tmp
zfs set mountpoint=${DESTDIR}/usr ${ROOTPOOL}/usr
zfs set mountpoint=${DESTDIR}/var ${ROOTPOOL}/var
if [ "${DATAPOOL}" != "${ROOTPOOL}" ]; then
zfs set mountpoint=${DESTDIR}/usr ${DATAPOOL}/usr;
zfs set mountpoint=${DESTDIR}/var ${DATAPOOL}/var;
fi
mkdir ${DESTDIR}/proc
mkdir ${DESTDIR}/usr/compat/linux/proc
chmod 1777 ${DESTDIR}/tmp
chmod 1777 ${DESTDIR}/var/tmp
mkdir ${DESTDIR}/media/a
mkdir ${DESTDIR}/media/cdrom
mkdir ${DESTDIR}/media/dvdrom
mkdir ${DESTDIR}/media/dosimage
mkdir ${DESTDIR}/media/floppy
mkdir ${DESTDIR}/media/isoimage
mkdir ${DESTDIR}/media/udfimage
mkdir ${DESTDIR}/media/ufsimage
ln -s usr/compat ${DESTDIR}/compat
Pick one of these two shell scripts to extract a base system into ${DESTDIR}:
#!/bin/sh
# Copyright © 2013, Trond Endrestøl <Trond.Endrestol@ximalas.info>
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
if [ -z "${DESTDIR}" ]; then
echo "$0: you must set the environment variable DESTDIR to the destination directory" >/dev/stderr;
echo "$0: e.g. export DESTDIR=/tmp/zroot" >/dev/stderr;
exit 69;
fi
if [ ! -d "${DESTDIR}" ]; then
echo "$0: destination directory ${DESTDIR} does not exist" >/dev/stderr;
echo "$0: maybe mkdir -p ${DESTDIR} needs to be run" >/dev/stderr;
exit 69;
fi
if ! zfs get mountpoint "${DESTDIR}" >/dev/null 2>/dev/null; then
echo "$0: destination directory ${DESTDIR} is not a ZFS filesystem" >/dev/stderr;
exit 69;
fi
cd /dist/8.*/base
echo "$0: Please answer y to the following question!"
./install.sh
# Answer y
cd ../games
./install.sh
cd ../info
./install.sh
cd ../lib32 && ./install.sh
cd ../manpages
./install.sh
cd ../kernels
./install.sh generic
cd ${DESTDIR}/boot
rmdir kernel
mv GENERIC kernel
#!/bin/sh
# Copyright © 2013, Trond Endrestøl <Trond.Endrestol@ximalas.info>
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
if [ -z "${DESTDIR}" ]; then
echo "$0: you must set the environment variable DESTDIR to the destination directory" >/dev/stderr;
echo "$0: e.g. export DESTDIR=/tmp/zroot" >/dev/stderr;
exit 69;
fi
if [ ! -d "${DESTDIR}" ]; then
echo "$0: destination directory ${DESTDIR} does not exist" >/dev/stderr;
echo "$0: maybe mkdir -p ${DESTDIR} needs to be run" >/dev/stderr;
exit 69;
fi
if ! zfs get mountpoint "${DESTDIR}" >/dev/null 2>/dev/null; then
echo "$0: destination directory ${DESTDIR} is not a ZFS filesystem" >/dev/stderr;
exit 69;
fi
cd ${DESTDIR}
tar xvvf /usr/freebsd-dist/kernel.txz
tar xvvf /usr/freebsd-dist/base.txz
tar xvvf /usr/freebsd-dist/lib32.txz
tar xvvf /usr/freebsd-dist/doc.txz
tar xvvf /usr/freebsd-dist/games.txz
Here’s a script for setting the final mountpoints:
#!/bin/sh
# Copyright © 2013, Trond Endrestøl <Trond.Endrestol@ximalas.info>
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
if [ -z "${ROOTPOOL}" ]; then
echo "$0: you must set the environment variable ROOTPOOL to the name of your root pool" >/dev/stderr;
echo "$0: e.g. export ROOTPOOL=zroot" >/dev/stderr;
exit 69;
fi
if ! zpool list "${ROOTPOOL}" >/dev/null 2>/dev/null; then
echo "$0: root pool ${ROOTPOOL} does not exist" >/dev/stderr;
echo "$0: try: zpool create -o cachefile=/tmp/zpool.cache -O mountpoint=legacy ${ROOTPOOL} ..." >/dev/stderr;
exit 69;
fi
if [ -z "${DATAPOOL}" ]; then
echo "$0: you must set the environment variable DATAPOOL to the name of your data pool" >/dev/stderr;
echo "$0: e.g. export DATAPOOL=zdata" >/dev/stderr;
echo "$0: your data pool can be the same as your root pool" >/dev/stderr;
echo "$0: e.g. export DATAPOOL=\${ROOTPOOL}" >/dev/stderr;
exit 69;
fi
if [ "${DATAPOOL}" != "${ROOTPOOL}" ]; then
if ! zpool list "${DATAPOOL}" >/dev/null 2>/dev/null; then
echo "$0: data pool ${DATAPOOL} does not exist" >/dev/stderr;
echo "$0: try: zpool create -o cachefile=/tmp/zpool.cache -O mountpoint=legacy ${DATAPOOL} ..." >/dev/stderr;
exit 69;
fi;
fi
if [ -z "${RELEASEDATE}" ]; then
echo "$0: you must set the environment variable RELEASEDATE to the date of the release you are installing" >/dev/stderr;
echo "$0: e.g. export RELEASEDATE=20130602" >/dev/stderr;
exit 69;
fi
if [ -z "${RELEASEREV}" ]; then
echo "$0: you must set the environment variable RELEASEREV to the Subversion revision number of the release you are installing" >/dev/stderr;
echo "$0: e.g. export RELEASEREV=251259" >/dev/stderr;
exit 69;
fi
cd /
zfs set readonly=on ${ROOTPOOL}/var/empty
zfs unmount -a
zfs inherit mountpoint ${ROOTPOOL}/ROOT/${RELEASEDATE}-r${RELEASEREV}
zfs set mountpoint=/home ${DATAPOOL}/home
zfs set mountpoint=/media ${ROOTPOOL}/media
zfs set mountpoint=/nfs ${ROOTPOOL}/nfs
zfs set mountpoint=/tmp ${ROOTPOOL}/tmp
zfs set mountpoint=/usr ${ROOTPOOL}/usr
zfs set mountpoint=/var ${ROOTPOOL}/var
if [ "${DATAPOOL}" != "${ROOTPOOL}" ]; then
zfs set mountpoint=/usr ${DATAPOOL}/usr;
zfs set mountpoint=/var ${DATAPOOL}/var;
fi
zfs unmount -a
Constructive comments are always welcome.