Mirroring root disk using SVM

There are about 487359 documents on the Internet about how to mirror root disk in Solaris. So, here is 487360th.

The assumptions are following: the first disk has Solaris already installed, root slice is slice 1, and the disks are identical with the same size and geometry. If they have different cylinder, head, sector count or different size you will have to fiddle with sizing slices more.

The first step is to recreate the same slice arrangement on the second disk:

bash-3.00# prtvtoc /dev/rdsk/c1t0d0s2 | fmthard -s - /dev/rdsk/c1t1d0s2
fmthard:  New volume table of contents now in place.

You can check both disks have the same VTOC using prtvtoc command:

bash-3.00# prtvtoc /dev/rdsk/c1t0d0s2
* /dev/rdsk/c1t0d0s2 partition map
* Dimensions:
*     512 bytes/sector
*     424 sectors/track
*      24 tracks/cylinder
*   10176 sectors/cylinder
*   14089 cylinders
*   14087 accessible cylinders
* Flags:
*   1: unmountable
*  10: read-only
*                          First     Sector    Last
* Partition  Tag  Flags    Sector     Count    Sector  Mount Directory
0      3    01          0   4100928   4100927
1      2    00    4100928  20484288  24585215
2      5    00          0 143349312 143349311
3      8    00   24585216 118672512 143257727
7      0    00  143257728     91584 143349311

Now we have to create state database replicas on slice 7. We will be adding two replicas to each slice:

bash-3.00# metadb -a -f -c3 /dev/dsk/c1t0d0s7
bash-3.00# metadb -a -f -c3 /dev/dsk/c1t1d0s7

Database replicas are crucial part of SVM. Here is some important information about how they work, how many you need, etc.

Since the database replicas are in place we can start creating metadevices. The following commands will create metadevice d31 from slice c1t0d0s3, and metadevice d32 from slice c1t1d0s3. Then we create mirror d30 with d31 attached as a submirror. Finally we will attach submirror d32 to mirror d30. Once d32 is attached, the mirror d30 will automatically start syncing.

bash-3.00# metainit -f d31 1 1 c1t0d0s3
d31: Concat/Stripe is setup
bash-3.00# metainit -f d32 1 1 c1t1d0s3
d32: Concat/Stripe is setup
bash-3.00# metainit d30 -m d31
d30: Mirror is setup
bash-3.00# metattach d30 d32
d30: submirror d32 is attached

The procedure is the same for all other mirrors you might want to create. Root filesystem is slightly different. First, you will have to create your submirrors. Then you will have to attach submirror with existing root filesystem, in this case d11, to the new mirror metadevice d10. Then you will have to run metaroot command. It will alter / entry in /etc/vfstab. Finally, you flush the filesystem using lockfs command and reboot.

bash-3.00# metainit -f d11 1 1 c1t0d0s1
d31: Concat/Stripe is setup
bash-3.00# metainit -f d12 1 1 c1t1d0s1
d32: Concat/Stripe is setup
bash-3.00# metainit d10 -m d11
d30: Mirror is setup
bash-3.00# metaroot d10
bash-3.00# lockfs -fa
bash-3.00# reboot

When the system reboots, you can attach the second submirror to d10 as follows:

bash-3.00# metattach d10 d12

You can check the sync progress using metastat command. Once all mirrors are synced up the next step is to configure the new swap metadevice, in my case d0, to be crash dump device. This is done using dumpadm command:

bash-3.00# dumpadm
Dump content: kernel pages
Dump device: /dev/dsk/c1t0d0s0 (dedicated)
Savecore directory: /var/crash/ultra
Savecore enabled: yes
bash-3.00# dumpadm -d /dev/md/dsk/d0

The final step is to modify PROM. First we need to find out which two physical devices c1t0d0 and c1t1d0 refer to:

bash-3.00# ls -l /dev/dsk/c1t0d0s1
lrwxrwxrwx   1 root     root          43 Mar  4 14:38 /dev/dsk/c1t0d0s1 -> ../../devices/pci@1c,600000/scsi@2/sd@0,0:b
bash-3.00# ls -l /dev/dsk/c1t1d0s1
lrwxrwxrwx   1 root     root          43 Mar  4 14:38 /dev/dsk/c1t1d0s1 -> ../../devices/pci@1c,600000/scsi@2/sd@1,0:b

The physical device path is everything starting from /pci…. Please make a note of sd towards the end of the device string. When creating device aliases below, sd will have to be changed to disk.

Now we create two device aliases called root and backup_root. Then we set boot-device to be root and backup_root. The :b refers to slice 1(root) on that particular disk.

bash-3.00# eeprom "use-nvramrc?=true"
bash-3.00# eeprom "nvramrc=devalias root /pci@1c,600000/scsi@2/disk@0,0 devalias backup_root /pci@1c,600000/scsi@2/disk@1,0"
bash-3.00# eeprom "boot-device=root:b backup_root:b net"

Now we can test that the system boot from both root and backup_root devices.

There is one more optional step. Adding two kernel tunables to /etc/system file. The first one is md_mirror:md_resync_bufsz which will speed up mirror resync. The second one is md:mirrored_root_flag. When this flag is enabled the system will boot even if less than majority of database replicas is available. Personally, I do not use the second tunable. More on these can be found in Solaris Tunable Parameters Refernce Guide.