Converting a FreeNAS stripe to mirrored drive

RAIDZ is a powerful tool, and FreeNAS makes it easier to use via the GUI, but there are a number of advanced things you can’t do in the GUI alone.

In this case, I had an expanded RAIDZ-1 volume with a single striped disk (by accident), and I wanted to convert that striped disk to a mirrored one.  You could also use the same steps to convert a single striped disk (yes a single disk is still labeled as striped) to a mirrored disk.

There are a few other sites that provide the commands, but they don’t do a good job of explaining what the commands are doing.  I’ll try to clear that up!

Determine that name of the new drive.  You can do this within the GUI.  Disks are usually named /dev/ada0, /dev/ada1, etc. In my case (using a PERC H310 with Avago firmware) they show up as /dev/da0, /dev/da1, etc.  The newest drive will have the highest number.  You can also use the SMART test to verify the drive by serial number by running:
smartctl -a /dev/<yournewdrive> | more

Once you determine the correct new drive, remove any existing partitions with:
gpart destroy -F /dev/<yournewdrive>

When all partitions are deleted you can then create the ZVOL partitions.  First start by creating the partition table of type gpt with:
gpart create -s gpt /dev/<yournewdrive>

With the partition table created, you can now add the partitions. All drives get 2GB reserved for swap, and the rest can be used for the ZVOL.  First create the 2GB swap partition (partition 1), which starts at an offset of 128 sectors (which is reserved for the partition table):
gpart add -i 1 -b 128 -t freebsd-swap -s 2g /dev/<yournewdrive>

Now you can create the ZVOL partition (partition 2), which is essentially the rest of the disk space:
gpart add -i 2 -t freebsd-zfs /dev/<yournewdrive>

Next check your work:
gpart show /dev/<yournewdrive>

If you did everything correctly, you should end up with a table like this (in my case for /dev/da5, which is a 4TB drive):

[root@nas ~]# gpart show /dev/da5                                               
=>        34  7814037101  da5  GPT  (3.6T)                                      
          34          94       - free -  (47K)                                  
         128     4194304    1  freebsd-swap  (2.0G)                             
     4194432  7809842696    2  freebsd-zfs  (3.6T)                              
  7814037128           7       - free -  (3.5K)    

If you find you’ve done something wrong, you can always destroy the partition table and start over again.

With the drive partitioned, you can now add it to the pool.  This part is tricky, because you need to do it by GPTID, which is a long hexidecimal code.  If possible, do this using an actual SSH session to your server, because you can’t copy and paste (to my knowledge) to the shell available in the web browser.  To determine the GPTID of each disk, run:
zpool status

You will see something like this:

  pool: VOL1                                                                                                                        
 state: ONLINE                                                                                                                      
  scan: scrub repaired 0 in 0h17m with 0 errors on Sun Mar 19 00:17:55 2017                                                         
config:                                                                                                                             
                                                                                                                                    
        NAME                                          STATE     READ WRITE CKSUM                                                    
        VOL1                                          ONLINE       0     0     0                                                    
          gptid/c3b13e97-ef38-11e6-9be5-74867ad1a828  ONLINE       0     0     0                                                    
        cache                                                                                                                       
          gptid/f36a38d3-1744-11e7-8856-0090fa79871a  ONLINE       0     0     0                                                    
                                                                                                                                    
errors: No known data errors 

Those gptid/<GPTID> values are the descriptors you’ll need.  Find the one for the existing drive and copy it to a text editor (notepad).  Then run:
glabel status

Here you will see a list of every drive in the system with the gptid/<GPTID> names for each.  Find the one that matches the new disk (it’s listed multiple times for each disk, so make sure you select the GPTID that matches the ZVOL, not the swap partition) and copy that to notepad as well.

Now you will need to add the disk to the zpool:
zpool attach <volumename> /dev/gptid/<existing disk GPTID> /dev/gptid/<new disk GPTID>
where volumename = the name or your zpool volume.

If all went well, the disk will now be added as a mirror, and the system will begin to resilver (copy all data over to create the mirror).  You can check this in a number of places, but one of the easiest is the GUI.  Go to the storage pane, click on the volume, then click on the Volume Status button at the bottom.  You will then see status like this:

Resilver of an array after the mirror was added.

You can also run zpool status again, which will now show the disk in the list and indicate a resilvering status until complete.  The status light will also go critical in the GUI until the resilver is complete, but there is no reason to worry and all your data will be available during this process.

That’s it!  You’ve successfully created a mirrored disk array without having to wipe the original disk and start from scratch.

A summary of commands:

Get drive name: smartctl -a /dev/<yournewdrive> | more
Clear partitions: gpart destroy -F /dev/<yournewdrive>
Create partition table: gpart create -s gpt /dev/<yournewdrive>
Create swap partition: gpart add -i 1 -b 128 -t freebsd-swap -s 2g /dev/<yournewdrive>
Create ZVOL partition: gpart add -i 2 -t freebsd-zfs /dev/<yournewdrive>
Check your work: gpart show /dev/<yournewdrive>
Get GPTID of existing drive: zpool status
Get GPTID of new drive: glabel status
Add disk mirror: zpool attach <volumename> /dev/gptid/<existing disk GPTID> /dev/gptid/<new disk GPTID>
Check for resilver: zpool status

3 thoughts on “Converting a FreeNAS stripe to mirrored drive”

  1. I had a 2 disk stripe and added 2 new disks as mirror. followed your instructions on freenas 9.10 and it worked nicely, just do every step twice, once for each disk.

    2 thigs to add:
    gpart create -s /dev/
    should be
    gpart create -s gpt /dev/

    and
    my disks gave me two gptids, one for each partition, I used the one for the ZVOL (obvious, but was mentioned in the text like each disk only has one gptid)

    again, thanks a lot!

    1. Thanks for catching those mistakes. I’ve updated the article, so hopefully it will be more straightforward for the next reader!

Leave a Reply

Your email address will not be published. Required fields are marked *