BFUing a Solaris Express Community Edition to build 128

This blog entry is for the people who can’t wait until Build 129 of SXCE or the the OpenSolaris Build 128 next week to get the fingers onto ZFS deduplication. Please don’t use it on your production SXCE or on your workstation. I’ve used a cloned snapshot of my SXCE snv_127 installation. It’s just for the people that really can’t wait!

# cat /etc/release 
                  Solaris Express Community Edition snv_127 X86
           Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
                        Use is subject to license terms.
                           Assembled 05 November 2009

This tutorial will guide you to the needed steps in order to BFU your installation to snv_128. I will not give you many explanations, as you should be reasonable fluent in what you do when you attempt to try this stuff.
Alan Hargreaves gave the really good advice to create a copy of your boot-environment with lucreate before starting to BFU. When you have a problem while BFUing your installation, you can simply revert to your unchanged boot environment and you have an un-bfued environment to further updates (that important, because there is a simple rule: Once you start to BFU, you have to BFU forever this installation, as BFU doesn’t update any files controlling other system management processes in regard of the packages on your disk) . I made something like that by using a ZFS clone of the emulated volume containing the virtual disk of my Solaris Express Community Edition installation. At first you have to download the BFU archive. BFU stands for Blindingly Fast Update. Instead of installing packages, it just copies some cpio archives on your installation. It’s really fast, but it’s brute force. Okay, download the archive first.

# wget
--2009-11-25 17:23:41--
Connecting to connected.
Proxy request sent, awaiting response... 200 OK
Length: 152087422 (145M) [application/x-tar]
Saving to: `on-bfu-nightly-osol-nd.i386.tar.bz2'

100%[=============================================================>] 152,087,422     --.-K/s   in 0.00s   

2009-11-25 17:19:52 (51.2 MB/s) - `SUNWonbld.i386.tar.bz2' saved [152087422/152087422]

The tools to BFU an installation are not part of the regular installation. You have to download the SUNWonbld package from the Sun website, too:

# wget
--2009-11-25 17:19:52--
Connecting to connected.
Proxy request sent, awaiting response... 200 OK
Length: 740031 (723K) [application/x-tar]
Saving to: `SUNWonbld.i386.tar.bz2'

100%[=============================================================>] 740,031     --.-K/s   in 0.01s   

2009-11-25 17:19:52 (51.2 MB/s) - `SUNWonbld.i386.tar.bz2' saved [740031/740031]

Decompress and untar the bziped tarball of the package:

# bunzip2 SUNWonbld.i386.tar.bz2 
# tar xf SUNWonbld.i386.tar 
# ls
SUNWonbld.i386.tar                   local.profile
archives-nightly-osol-nd             on-bfu-nightly-osol-nd.i386.tar.bz2
local.cshrc                          onbld
# cd onbld/
# ls

Install the package

# pkgadd -d . SUNWonbld

Processing package instance <SUNWonbld> from </export/home/jmoekamp/onbld>

OS-Net Build Tools(i386) 11.11,REV=2009.
Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
Use is subject to license terms.
[... a lot of stuff deleted ...]
[ verifying class <none> ]
/opt/onbld/bin/i386/install.bin <linked pathname>

Installation of <SUNWonbld> was successful.

Now you have to prepare the environment that runs the BFU.

# export FASTFS=/opt/onbld/bin/`uname -p`/fastfs
# export GZIPBIN=/usr/bin/gzip
# export BFULD=/opt/onbld/bin/`uname -p`/bfuld
# export PATH=$PATH:/opt/onbld/bin/:opt/onbld/bin/`uname -p`

Now you can start the BFU run …

# bfu /export/home/jmoekamp/archives-nightly-osol-nd/i386/
Copying /opt/onbld/bin/bfu to /tmp/bfu.1382
Executing /tmp/bfu.1382 /export/home/jmoekamp/archives-nightly-osol-nd/i386/

Loading /export/home/jmoekamp/archives-nightly-osol-nd/i386/ on /

Creating bfu execution environment ...
/tmp/bfu.1382[3376]: /net/onnv.eng/export/onnv-gate/public/bin/acr: cannot open
chmod: WARNING: can't access /tmp/bfubin/acr
/tmp/bfu.1382[3376]: /usr/bin/print: cannot open
chmod: WARNING: can't access /tmp/bfubin/print
Verifying archives ...
Performing basic sanity checks ...
/etc/svc/repository.db: passed integrity check
Disabling kernel module unloading ... moddebug:       0               =       0x20000
Unmounting /lib/ ...
Disabling sendmail temporarily ...
Disabling remote logins ...
Disabling syslog temporarily ...
Killing httpd ...
Disabling fmd temporarily ...
Killing nscd ...
Turning on delayed i/o ...
Filesystem           Mode      
/                    safe      
/usr                 safe      

Saving configuration files in /bfu.child ... 4704 blocks
Removing init.d links ... done.
Removing obsolete rc.d scripts ... done.
Removing EOF Smartcard... done.
Extracting platform ufs modules for boot  block ... 15320 blocks
Extracting usr/platform ufs modules for boot  block ... 3670 blocks
Extracting grub for boot  block ... 1890 blocks
Creating GRUB menu in /
bootadm: failed to determine fdisk partition: /dev/dsk/c0d0s0
bootadm: cannot get (hd?,?,?) for menu. menu not on bootdisk: /dev/rdsk/c0d0s0
Installing grub on /dev/rdsk/c0d0s0
stage1 written to partition 0 sector 0 (abs 16065)
stage2 written to partition 0, 273 sectors starting at 50 (abs 16115)
Extracting generic.usr ... 444062 blocks
Extracting i86pc.usr ... 3670 blocks
Extracting i86xpv.usr ... 1330 blocks
Extracting generic.lib ... 68160 blocks
Extracting generic.sbin ... 3820 blocks
Extracting generic.kernel ... 245092 blocks
Extracting generic.root ... 12450 blocks
Extracting i86pc.root ... 15320 blocks
Extracting i86xpv.root ... 13990 blocks
Extracting i86hvm.root ... 2550 blocks
Extracting i86pc.boot ... 1890 blocks

Removing duplicate kernel binaries ...

SUNWcry, SUNWcryr, SUNWn2cpact.v removal cleanup...

    Removing packages...

Cleaning up old Kerberos GSS-API mechanisms...

Cleaning up old RBAC profiles... 

Restoring configuration files.

NEW conflict: boot/grub/menu.lst
NEW conflict: boot/solaris/bootenv.rc
     restore: boot/solaris/devicedb/master
NEW conflict: etc/default/init
     restore: etc/
     restore: etc/dladm/datalink.conf
     restore: etc/driver_aliases
NEW conflict: etc/driver_classes
     restore: etc/inet/inetd.conf
     restore: etc/inet/services
     restore: etc/inet/sock2path
     restore: etc/inittab
     restore: etc/krb5/krb5.conf
      update: etc/ksh.kshrc
NEW conflict: etc/minor_perm
     restore: etc/name_to_major
      update: etc/name_to_sysnum
NEW conflict: etc/nsswitch.conf
     restore: etc/passwd
NEW conflict: etc/path_to_inst
NEW conflict: etc/power.conf
NEW conflict: etc/remote
      update: etc/security/audit_event
NEW conflict: etc/security/auth_attr
     restore: etc/security/device_policy
NEW conflict: etc/security/exec_attr
     restore: etc/security/extra_privs
NEW conflict: etc/security/prof_attr
      update: etc/security/tsol/tnzonecfg
NEW conflict: etc/shadow
NEW conflict: etc/user_attr
NEW conflict: etc/vfstab
      update: kernel/drv/emlxs.conf
     restore: kernel/drv/mpt.conf
     restore: kernel/drv/mpt_sas.conf
     restore: kernel/drv/sd.conf
    preserve: kernel/misc/amd64/usbs49_fw
    preserve: kernel/misc/usbs49_fw
    preserve: var/adm/utmpx
    preserve: var/adm/wtmpx
    preserve: var/saf/zsmon/log
     restore: var/spool/cron/crontabs/root
NEW conflict: etc/mpapi.conf
NEW conflict: etc/hba.conf
NEW conflict: etc/ima.conf
updating /platform/i86pc/amd64/boot_archive
updating /platform/i86pc/boot_archive

For each file in conflict, your version has been restored.
The new versions are under /bfu.conflicts.


To install resolved changes required for reboot in the boot
archive, invoke 'bootadm update-archive'

Removing obsolete smf services ...
Disabling unneeded inetd.conf entries ...
Connecting platform and name service profiles ...
Marking converted services as enabled ...
cp: cannot access /net/greenline.eng/meta0/smf/post-5090532/sysidtool.xml
bfu: could not copy /net/greenline.eng/meta0/smf/post-5090532/sysidtool.xml
cp: cannot access /net/greenline.eng/meta0/smf/post-5090532/kdmconfig.xml
bfu: could not copy /net/greenline.eng/meta0/smf/post-5090532/kdmconfig.xml
cp: cannot access /net/greenline.eng/meta0/smf/svc-kdmconfig
bfu: could not copy /net/greenline.eng/meta0/smf/svc-kdmconfig
Converted platform/i86pc/kdmconfig
Upgrade of unknown took 19:03.
Turning off delayed i/o and syncing filesystems ...
Filesystem           Mode      
/                    safe      
/usr                 safe      

Entering post-bfu protected environment (shell: ksh).
Edit configuration files as necessary, then reboot.

There are several conflicts in files on your system. You can resolve them manually or use the script /opt/onbld/bin/acr to resolve them automatically. Usually i start the update of my boot-archive afterwards.

bfu# bootadm update-archive
updating //platform/i86pc/boot_archive
updating //platform/i86pc/amd64/boot_archive

Reboot the System …

bfu# reboot
Read from remote host Connection reset by peer
Connection to closed.

Try to login into your system:

jmoekamp@hivemind:~/Downloads# ssh jmoekamp@
Last login: Wed Nov 25 16:56:13 2009 from
Sun Microsystems Inc.   SunOS 5.11      snv_128 November 2009
bfu'ed from /export/home/jmoekamp/archives-nightly-osol-nd/i386/ on 2009-11-25
Sun Microsystems Inc.   SunOS 5.11      snv_127 November 2008

Ta Da … a brand new snv_128 system to test deduplication. Let’s do a quick test. Create a small ramdisk ….

# ramdiskadm -a test 128m

Create a testpool in it:

# zpool create testpool /dev/ramdisk/test

Usually i’m switching my zpools to sha256 afterwards

# zfs set checksum=sha256 testpool 
# zfs get checksum testpool
testpool  checksum  sha256     local

Okay … let’s activate zfs deduplication:

# zfs set dedup=on testpool

Copy a file three times into a deduplicating filesystem:

# cp /usr/bin/xsane /testpool/xsane
# zfs list
testpool   160K  90.9M    86K  /testpool
# cp /usr/bin/xsane /testpool/xsane2
# zfs list
testpool  3.67M  89.1M  3.59M  /testpool
# cp /usr/bin/xsane /testpool/xsane3
# zfs list
testpool  5.42M  89.1M  5.34M  /testpool

Look at the columns USED and AVAIL at each iteration. Neat :)