I have long contended that for small, home NAS systems, mirrors are the way to go. You don’t have to calculate how much parity you need, similarly, the backup size is also obvious. It costs less upfront, you only need two disks. And because you only need two disks, you can get the biggest disks you can afford, which usually have excellent GB/cent cost ratios.
Finally, you can grow mirrors! As long as your storage needs don’t outstrip storage space growth, you can grow your mirrors very economically. Case in point, I was running a 2TB mirror which was getting close to 80% full. I was able to buy 8TB disks very cheaply, and grow my mirror to 8TB.
First things first, don’t be an idiot, this guide is how to modify storage. Triple check everything, and make sure you have backups. This guide also assumes the disks are blank, i.e. unformatted.
Step 1: Install new drive
I had no spare bays/SATA connections, but if you did, you could potentially do this in a more safer way by adding the new disks to a mirror to create a 3 or 4-way mirror, and then pulling the old disks out.
I had to do it more riskily by degrading the mirror. First, I powered down the NAS. Then I replaced one of the old disks in the mirror with a new one and powered up again. First, let’s check the right disk was pulled:
$ zpool status pool
pool: pool
state: DEGRADED
status: One or more devices could not be opened. Sufficient replicas exist for
the pool to continue functioning in a degraded state.
action: Attach the missing device and online it using 'zpool online'.
see: http://illumos.org/msg/ZFS-8000-2Q
scan: scrub repaired 0 in 0 days 02:49:09 with 0 errors on Sun May 13 02:49:10 2018
config:
NAME STATE READ WRITE CKSUM
pool DEGRADED 0 0 0
mirror-0 DEGRADED 0 0 0
11300205822825511459 UNAVAIL 0 0 0 was /dev/gptid/d8bea02b-178c-11e8-9b2e-28924a390410
gptid/d9ae78ea-178c-11e8-9b2e-28924a390410 ONLINE 0 0 0
errors: No known data errors
As expected, the mirror is degraded. So, now to figure out which drive is the new drive:
$ ls -1 /dev/ada*
/dev/ada0
/dev/ada1
/dev/ada1p1
/dev/ada1p2
/dev/ada2
/dev/ada2p1
/dev/ada3
/dev/ada3p1
What’s going on? Well, drives are mounted in /dev
and receive a name, e.g. ada1
. The partitions are also mounted as /dev/ada1p1
and /dev/ada1p2
. So it’s already pretty obvious that the new drive is ada0
.
Just to check, we’ll look at the labels and partitions. BSD labels drives with UUIDs, since the name assigned in /dev
is basically random, and drives could get reassigned on start-up.
$ glabel status
Name Status Components
gptid/23edea4a-1742-11e8-b551-28924a390410 N/A da0p1
gptid/d9ae78ea-178c-11e8-9b2e-28924a390410 N/A ada1p2
gptid/d98b522f-178c-11e8-9b2e-28924a390410 N/A ada1p1
$ gpart show
=> 40 15663024 da0 GPT (7.5G)
40 1024 1 bios-boot (512K)
1064 15661992 2 freebsd-zfs (7.5G)
15663056 8 - free - (4.0K)
=> 40 3907029088 ada1 GPT (1.8T)
40 88 - free - (44K)
128 4194304 1 freebsd-swap (2.0G)
4194432 3902834688 2 freebsd-zfs (1.8T)
3907029120 8 - free - (4.0K)
$ glabel list | grep ada0
$
Ignore da0
, it is the OS USB disk. The blank disk is ada0
, it has no labels or partition map.
Step 2: Create GPT partition map
Create the partition map on the new disk:
$ sudo gpart create -s gpt ada0
ada0 created
Now re-create partitions similar to the other disk in the mirror. My distro FreeNAS allocates a bit of swap space on all drives, so we want to replicate that. Get the parameters for gpart add
from gpart list
, -t
is the type, -b
is the the starting offset, -i
is the index, and -s
is the size. I don’t know why FreeNAS sets a starting offset for the swap partition, but whatever.
$ gpart show ada0
=> 40 15628053088 ada0 GPT (7.3T)
40 15628053088 - free - (7.3T)
$ gpart show ada1
=> 40 3907029088 ada1 GPT (1.8T)
40 88 - free - (44K)
128 4194304 1 freebsd-swap (2.0G)
4194432 3902834688 2 freebsd-zfs (1.8T)
3907029120 8 - free - (4.0K)
$ gpart list ada1
[...]
scheme: GPT
Providers:
1. Name: ada1p1
Mediasize: 2147483648 (2.0G)
[...]
type: freebsd-swap
index: 1
end: 4194431
start: 128
2. Name: ada1p2
Mediasize: 1998251360256 (1.8T)
[...]
type: freebsd-zfs
index: 2
end: 3907029119
start: 4194432
Consumers:
1. Name: ada1
Mediasize: 2000398934016 (1.8T)
Sectorsize: 512
Stripesize: 4096
Stripeoffset: 0
Mode: r1w1e3
$ sudo gpart add -t freebsd-swap -b 128 -i 1 -s 2G ada0
ada0p1 added
$ gpart show ada0
=> 40 15628053088 ada0 GPT (7.3T)
40 88 - free - (44K)
128 4194304 1 freebsd-swap (2.0G)
4194432 15623858696 - free - (7.3T)
$ gpart show ada1
=> 40 3907029088 ada1 GPT (1.8T)
40 88 - free - (44K)
128 4194304 1 freebsd-swap (2.0G)
4194432 3902834688 2 freebsd-zfs (1.8T)
3907029120 8 - free - (4.0K)
$ sudo gpart add -t freebsd-zfs -i 2 ada0
ada0p2 added
$ gpart show ada0
=> 40 15628053088 ada0 GPT (7.3T)
40 88 - free - (44K)
128 4194304 1 freebsd-swap (2.0G)
4194432 15623858688 2 freebsd-zfs (7.3T)
15628053120 8 - free - (4.0K)
$ gpart show ada1
=> 40 3907029088 ada1 GPT (1.8T)
40 88 - free - (44K)
128 4194304 1 freebsd-swap (2.0G)
4194432 3902834688 2 freebsd-zfs (1.8T)
3907029120 8 - free - (4.0K)
Step 3: Add the new disk/partition to the mirror
Now that the disk has a label/UUID, it’s time to stop referring to it as ada0
where possible.
$ glabel status
Name Status Components
gptid/23edea4a-1742-11e8-b551-28924a390410 N/A da0p1
gptid/d9ae78ea-178c-11e8-9b2e-28924a390410 N/A ada1p2
gptid/fa78eb2a-178f-11e8-99e9-28924a390410 N/A ada2p1
gptid/fb1b40fa-178f-11e8-99e9-28924a390410 N/A ada3p1
gptid/d98b522f-178c-11e8-9b2e-28924a390410 N/A ada1p1
gptid/e5ebdfcc-726e-11e8-a5a9-28924a390410 N/A ada0p1
gptid/03d44ba4-726f-11e8-a5a9-28924a390410 N/A ada0p2
$ gpart list ada0 | grep rawuuid
rawuuid: e5ebdfcc-726e-11e8-a5a9-28924a390410
rawuuid: 03d44ba4-726f-11e8-a5a9-28924a390410
$ zpool status pool
pool: pool
state: DEGRADED
status: One or more devices could not be opened. Sufficient replicas exist for
the pool to continue functioning in a degraded state.
action: Attach the missing device and online it using 'zpool online'.
see: http://illumos.org/msg/ZFS-8000-2Q
scan: scrub repaired 0 in 0 days 02:49:09 with 0 errors on Sun May 13 02:49:10 2018
config:
NAME STATE READ WRITE CKSUM
pool DEGRADED 0 0 0
mirror-0 DEGRADED 0 0 0
11300205822825511459 UNAVAIL 0 0 0 was /dev/gptid/d8bea02b-178c-11e8-9b2e-28924a390410
gptid/d9ae78ea-178c-11e8-9b2e-28924a390410 ONLINE 0 0 0
errors: No known data errors
In this case, the label is 03d44ba4-726f-11e8-a5a9-28924a390410
for the second partition, and I want to resilver from the online disk, d9ae78ea-178c-11e8-9b2e-28924a390410
:
$ sudo zpool attach pool \
/dev/gptid/d9ae78ea-178c-11e8-9b2e-28924a390410 \
/dev/gptid/03d44ba4-726f-11e8-a5a9-28924a390410
$ zpool status pool
pool: pool
state: DEGRADED
status: One or more devices is currently being resilvered. The pool will
continue to function, possibly in a degraded state.
action: Wait for the resilver to complete.
scan: resilver in progress since Sun Jun 17 13:54:32 2018
862G scanned at 464M/s, 3.13G issued at 31.4M/s, 1.70T total
3.12G resilvered, 0.18% done, 0 days 15:43:42 to go
config:
NAME STATE READ WRITE CKSUM
pool DEGRADED 0 0 0
mirror-0 DEGRADED 0 0 0
11300205822825511459 UNAVAIL 0 0 0 was /dev/gptid/d8bea02b-178c-11e8-9b2e-28924a390410
gptid/d9ae78ea-178c-11e8-9b2e-28924a390410 ONLINE 0 0 0
gptid/03d44ba4-726f-11e8-a5a9-28924a390410 ONLINE 0 0 0 (resilvering)
errors: No known data errors
Step 4: Wait
Resilvering takes time.
Step 5: Repeat with the other drive in the mirror
And please make sure you pull the right drive!
$ zpool status pool
pool: pool
state: DEGRADED
status: One or more devices is currently being resilvered. The pool will
continue to function, possibly in a degraded state.
action: Wait for the resilver to complete.
scan: resilver in progress since Sun Jun 17 18:10:33 2018
865G scanned at 183M/s, 331M issued at 4.67M/s, 1.70T total
323M resilvered, 0.02% done, no estimated completion time
config:
NAME STATE READ WRITE CKSUM
pool DEGRADED 0 0 0
mirror-0 DEGRADED 0 0 0
11300205822825511459 UNAVAIL 0 0 0 was /dev/gptid/d8bea02b-178c-11e8-9b2e-28924a390410
6780713986779558112 UNAVAIL 0 0 0 was /dev/gptid/d9ae78ea-178c-11e8-9b2e-28924a390410
gptid/03d44ba4-726f-11e8-a5a9-28924a390410 ONLINE 0 0 0
gptid/1d2d3246-7294-11e8-85fd-28924a390410 ONLINE 0 0 0 (resilvering)
errors: No known data errors
$ zpool status pool
pool: pool
state: DEGRADED
status: One or more devices could not be opened. Sufficient replicas exist for
the pool to continue functioning in a degraded state.
action: Attach the missing device and online it using 'zpool online'.
see: http://illumos.org/msg/ZFS-8000-2Q
scan: resilvered 1.70T in 0 days 02:58:23 with 0 errors on Sun Jun 17 21:08:56 2018
config:
NAME STATE READ WRITE CKSUM
pool DEGRADED 0 0 0
mirror-0 DEGRADED 0 0 0
11300205822825511459 UNAVAIL 0 0 0 was /dev/gptid/d8bea02b-178c-11e8-9b2e-28924a390410
6780713986779558112 UNAVAIL 0 0 0 was /dev/gptid/d9ae78ea-178c-11e8-9b2e-28924a390410
gptid/03d44ba4-726f-11e8-a5a9-28924a390410 ONLINE 0 0 0
gptid/1d2d3246-7294-11e8-85fd-28924a390410 ONLINE 0 0 0
errors: No known data errors
Step 6: Detach old disks and watch the mirror grow
$ sudo zpool detach pool 11300205822825511459
$ zpool status pool | grep 'state:'
state: DEGRADED
$ sudo zpool detach pool 6780713986779558112
$ zpool status pool
pool: pool
state: ONLINE
scan: resilvered 1.70T in 0 days 02:58:23 with 0 errors on Sun Jun 17 21:08:56 2018
config:
NAME STATE READ WRITE CKSUM
pool ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
gptid/03d44ba4-726f-11e8-a5a9-28924a390410 ONLINE 0 0 0
gptid/1d2d3246-7294-11e8-85fd-28924a390410 ONLINE 0 0 0
errors: No known data errors
$ zpool list -o name,size
NAME SIZE
pool 7.27T
freenas-boot 7.44G
Job done.