Install SmartOS and keep your existing pool

October 10, 2012

I am skipping the SmartOS introduction because Magnus Hedemark has us covered with Discovering SmartOS. Instead, I’ll dive straight in and tell you that it’s great as an all-in-one storage and virtualization server, despite only being branded as the latter. Maybe you’ve been using ESXi, Nexenta CP/NexentaStor, or OpenIndiana to fill this role (or even a combination of both on separate machines), but I assure you that it’s possible to have your cake and eat it too. The cake is not a lie!

Once you become familiar with the SmartOS way, you’ll discover that it wants you to start from scratch with clean disks. During the initial configuration, it will prompt you for the disks to use and create a pool named ‘zones’ for storing persistent data on. If you’re like me, you already have an existing data pool from a previous OS install and would like to serve up some zones and KVM instances along with your existing ZFS filesystems. Since the installer doesn’t have provisions for dealing with this scenario we need to improvise a little bit.

You will need a few things before you begin:

  • A SmartOS bootable USB key
  • Output from ‘zpool status’ so you know the drive names and which pool they’re currently in
  • Your existing system disks/OS or an OpenIndiana LiveCD
  • A spare drive SmartOS can temporarily use (all data on this drive will be lost)
  • Good backups of all your data, just in case

The basic steps to accomplish the magic are as follows:

  1. Boot into single user mode from your existing OS
  2. Rename any existing ZFS dataset that might be called ‘zones’:

    # zfs rename data/zones data/old_zones
    # zfs set mountpoint=/old_zones data/old_zones
  3. Export your old pool (mine was called data and is used as an example):

    # zpool export data
  4. Boot using the USB key, follow the prompts, and make sure you install onto the spare disk and not any of your existing data disks (you have that output from ‘zpool status’, right?). After the install, SmartOS should boot, your old data pool should be imported at the mount point specified in step 2, and your spare disk will have a ‘zones’ pool with the following new datasets:

    zones/config
    zones/cores
    zones/opt
    zones/swap
    zones/usbkey
    zones/var
  5. Prepare to transfer the new datasets to your old pool:

    # zfs snapshot -r zones@migrate
    # for dset in "config cores opt swap usbkey var"; do zfs send -R zones/${dset}@migrate | zfs recv data/${dset}; done
  6. Reboot into your previous OS (single-user mode) or a live CD so you can do an Indiana Jones style pool swap. This is necessary because you cannot export the new ‘zones’ pool while SmartOS is booted, and you need to be able to import your old pool as ‘zones’ to effectively rename it. With this done, make the swap:

    # zpool import data zones

    You will now technically have two pools called ‘zones’. Chances are good you will not be able to import the one that SmartOS created because it uses a newer ZFS pool version than what is available in other distros. If you don’t intend to use the spare drive in your system, you can power down, remove it, and boot back into SmartOS now. If you’d like to use the spare drive then follow the last step.
  7. Reboot back into SmartOS. When you do, you’ll be prompted to go through configuration again as a result of there being two ‘zones’ pools. Answer no to skip configuration and then you’ll be presented with a login prompt. Login with ‘root’ and the default single-user root password for your SmartOS version. These are text files found in the https://download.joyent.com/pub/iso/ directory, prefixed with SINGLE_USER_ROOT_PASSWD.*

    After you’re logged in, typing ‘zpool import’ should present you with two ‘zones’ pools. You should proceed to import your old data pool via its listed pool id, e.g:

    # zpool import -f 12736277524734292156

    Since you’re planning on using your spare drive, you can either go ahead and add it to the zones pool (as maybe a cache, log, or hot spare), or import it as a separate pool. To do the latter, import via the pool id and specify a new pool name, e.g:

    # zpool import -f 1265591459793332791 sparepool

In any case, you’ll want to make sure that the zones pool on the spare drive has been renamed or destroyed so it doesn’t interfere with your newly imported zones pool. Reboot again and if all goes well, SmartOS will come up configured and you’re good to go! You may now want to cleanup the @migrate snapshots. When you’re confident that you’ve made the right choice with SmartOS and don’t want to go back to your old setup, running ‘zpool upgrade’ is advised so you can take advantage of newer ZFS pool features.

I have personally used this procedure on two production systems and it works well (this blog is running on one of them). Both of these systems serve up ZFS filesystems via NFS to zones and KVM instances running on the same physical host, as well as other external hosts.

apt.zpool.org now hosts retired NCP3 repo

April 7, 2012

If you are running Nexenta Core Platform (NCP) 3.x and have been on a different planet for a few months, you may not have heard that NCP was discontinued and Illumian was created to take its place. The nexenta.org website has since been repurposed and there were some problems with the previous community hosted apt.nexenta.org. This is somewhat unfortunate for anybody that is still running NCP3 with a need for the original package repository. At Nexenta Systems, Inc. request, I have agreed to host the retired NCP3 repository for the community. For anyone still running NCP3 systems that have need of these bits, you can add the following line to your /etc/apt/sources.list file in place of any apt.nexenta.org lines:

deb http://apt.zpool.org/ncp3 hardy-unstable main contrib non-free

How to fix a stuck ZFS log device

January 10, 2012

I ran into a troublesome ZFS bug several months ago where a pool with a log device became “stuck”. The ‘zpool remove’ command would complete but would not remove the device. This was a bad place to be in, because the device was no longer usable, could not be removed, and would most likely prevent the pool from ever being exported and reimported again. Someone else had posted on the zfs-discuss mailing list about the same problem and put me in contact with George Wilson, who in turn put me on the right track to a successful workaround. Log devices exhibiting this behavior need to have a specific field of a data structure zeroed out, and then the remove command will actually finish removing the device.

The procedure for fixing this is:

Find the corresponding virtual memory hex address on the left for the stuck log device on the right.

# echo '::spa -v | mdb -k'
...
ffffff0946273d40 HEALTHY - /dev/dsk/c4t5000CCA000342E60d0s0
ffffff0946274380 HEALTHY - /dev/dsk/c7d0s0
- - - cache
ffffff094b069680 HEALTHY - /dev/dsk/c7d0s1

Find the corresponding virtual memory hex address on the left for the field vdev_stat.vs_alloc.

# echo 'ffffff0946273d40::print -a vdev_t vdev_stat' | mdb -k
vdev_stat = {
ffffff0946273f70 vdev_stat.vs_timestamp = 0x52bcba2a6c
ffffff0946273f78 vdev_stat.vs_state = 0
ffffff0946273f80 vdev_stat.vs_aux = 0
ffffff0946273f88 vdev_stat.vs_alloc = 0xfffffffffffe0000
ffffff0946273f90 vdev_stat.vs_space = 0x222c000000
ffffff0946273f98 vdev_stat.vs_dspace = 0x222c000000
ffffff0946273fa0 vdev_stat.vs_rsize = 0
ffffff0946273fa8 vdev_stat.vs_ops = [ 0x5, 0x1c, 0x20b, 0, 0, 0x92 ]
ffffff0946273fd8 vdev_stat.vs_bytes = [ 0, 0x12a000, 0x640000, 0, 0, 0 ]
ffffff0946274008 vdev_stat.vs_read_errors = 0
ffffff0946274010 vdev_stat.vs_write_errors = 0
ffffff0946274018 vdev_stat.vs_checksum_errors = 0
ffffff0946274020 vdev_stat.vs_self_healed = 0
ffffff0946274028 vdev_stat.vs_scan_removing = 0x1
ffffff0946274030 vdev_stat.vs_scan_processed = 0
}

Change the value. Depending on the size of the current value, you may need to use /Z0 to zero the field.

# echo 'ffffff0946273f88/Z0' | mdb -kw
0xffffff0946273f88: 0xffffffff00000000 = 0x0

Verify that ‘zpool iostat -v <pool>’ shows the alloc column for the stuck log device is now 0 and then re-issue the zpool remove command.

# zpool iostat -v data
capacity   operations bandwidth
pool                      alloc  free  read write  read write
------------------------- ----- ----- ----- ----- ----- -----
...
c4t5000CCA000342E60d0         0  137G     0     0     0     0
c7d0s0                    16.0E 9.94G     0     0     0     0
cache                         -     -     -     -     -     -
c7d0s1                    64.9G 7.78M    17    59  394K 7.07M
------------------------- ----- ----- ----- ----- ----- -----

# zpool remove data c4t5000CCA000342E60d0

I experienced this problem on NexentaCore 3.1 which shares the same kernel bits with NexentaStor 3.x. Someone apparently filed a bug with Oracle (CR 7000154) but the information is locked away behind their paid support portal for those that don’t have access. I haven’t looked recently but at the time there wasn’t an Illumos bug filed and it’s still not fixed. Hopefully the above information will help others experiencing this problem, however, please note that I am not responsible for any damage this might do to your data. Please make sure you have things backed up, and be aware that inputting anything to mdb in this manner can cause a kernel panic on a running system!