gmirror RAID-1 of 2-slices/disk? (not just 1 slice, not whole-disk ... )

Brendon Janos brendonj.lists at gmail.com
Mon Dec 17 16:27:54 PST 2007


Hi,

I've an amd64 box w/ two identical SATA drives, ad4 & ad6.

I've installed FreeBSD 6.2-RELEASE-p9 SMP onto two slices on ad4,
partitioned as:

	ad4s1:
		/
		/swap
		/usr
		/tmp
	
	ad4s2:
		/var/
		/var/db
		/var/spool
		/home

"All" I'd like to accomplish is to mirror each ad4 slice to ad6.  I
*thought* this was going to be straighforward ...

In addition to spending the weekend poring over threads here, and
everything else I could google, I've 'landed' @ these 3 primary
references,

  http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/geom-mirror.html
  http://people.freebsd.org/~rse/mirror/
  http://ezine.daemonnews.org/200502/diskmirror.html

Although generally helpful, they all detail whole-disk mirrors, and
mention -- without 'howto' detail -- slice mirrors.

I've attempted (detail below) to adapt the procedures to my 2-slice
scenario; unfrotunately, after slogging through, on reboot, at various
times I'm greeted by either:

 (1) a 'mountroot>' prompt, with a suddenly, completely non-responsive keyboard
 (2) an error message:
       "THE FOLLOWING FILE SYSTEMS HAD AN UNEXPECTED INCONSISTENCY
       ...
       Unknown Error. Help!"

As poignantly punctuated by the "Unknown Error. Help!", I've obviously
done something wrong.

Can someone please take a look at what I've done and suggest
appropriate corrections & improvements? Or, should I be using gvinum?

(Yes, I'm aware this all is 'tortured' ... which is consistent with my
current state!)

Thanks.

Brendon



# Assign VARs
setenv d1 "ad4"
setenv d2 "ad6"
setenv gm "gm0"

# zero out the 2nd disk
dd if=/dev/zero of=/dev/${d2} bs=512 count=79

# find the START & SIZE of each source slice
setenv start_s1 `fdisk /dev/${d1} | grep -A4 'partition 1' | grep 'start ' |\
    head -1 | sed -e 's;^.*start \([0-9]*\).*$;\1;'`
setenv start_s2 `fdisk /dev/${d1} | grep -A4 'partition 2' | grep 'start ' |\
    head -1 | sed -e 's;^.*start \([0-9]*\).*$;\1;'`

setenv size_s1 `fdisk /dev/${d1} | grep -A4 'partition 1' | grep ', size ' |\
    head -1 | sed -e 's;^.*size \([0-9]*\).*$;\1;'`
setenv size_s2 `fdisk /dev/${d1} | grep -A4 'partition 2' | grep ', size ' |\
    head -1 | sed -e 's;^.*size \([0-9]*\).*$;\1;'`

# decrement the size of each slice by 1
setenv size_s1 `expr $size_s1 - 1`
setenv size_s2 `expr $size_s2 - 1`


# create an FDISK config file for the target drive slices
cat << EOF > /tmp/fdisk_conf
 g c16383 h16 s63
 a 1
 p 1 165 $start_s1 $size_s1
 p 2 165 $start_s2 $size_s2
 p 3 0 0 0
 p 4 0 0 0
EOF

# create the target slices, loading a FreeBSD boot0 MBR into the active slice
fdisk -v -f/tmp/fdisk_conf -b/boot/boot0 -i /dev/${d2}

# assign gmirror labels to each target slice
gmirror label -v -n -b round-robin ${gm}s1 /dev/${d2}s1
gmirror label -v -n -b round-robin ${gm}s2 /dev/${d2}s2

# load
gmirror load

# check
gmirror status
	        Name    Status  Components
	mirror/gm0s1  COMPLETE  ad6s1
	mirror/gm0s2  COMPLETE  ad6s2


# place BSD partition disklabels onto gmirror slices
# reformatted, because I simply couldn't read the reference
# modified to sort partitions by OFFSET, so size corrections don't bomb
#!/bin/sh
for S in 1 2
do
	(bsdlabel /dev/mirror/${gm}s${S} | grep 'c:';                       \
	 bsdlabel /dev/${d1}s${S}        | grep '[abdefgh]:' | sort -k 3n ; \
	) | \
	awk 'BEGIN { sizeC = 0; n = 0; } \
	/c:/ { \
	 partC   = $1; \
	 sizeC   = $2; \
	 offsetC = $3; \
	 fstypeC = $4; \
	 fsizeC  = $5; \
	 bsizeC  = $6; \
	 printf("%s %d %s %s %s %s\n", \
			partC,    \
			sizeC,    \
			offsetC,  \
			fstypeC,  \
			fsizeC,   \
			bsizeC ); \
	 next;} \
	/[abdefgh]:/ { \
	 part   = $1; \
	 size   = $2; \
	 offset = $3; \
	 fstype = $4; \
	 fsize  = $5; \
	 bsize  = $6; \
	 if (sizeC > 0 && n+size > sizeC) { size = sizeC-n }; \
	 n += size; \
	 printf("%s %d %s %s %s %s\n", \
			part,   \
			size,   \
			offset, \
			fstype, \
			fsize,  \
			bsize ); }' > /tmp/bsdlabel_s${S}.txt

	bsdlabel -R /dev/mirror/${gm}s${S} /tmp/bsdlabel_s${S}.txt

done


# dump & restore filesystem data from first to second disk
#!/bin/sh
for S in 1 2
do
	for P in `bsdlabel /dev/${d1}s${S} | egrep '^ *[adefgh]:' | sed -e
's/^ *\([adefgh]\).*/\1/'`
	do
		FS=`egrep "^ */dev/${d1}s${S}${P}" /etc/fstab | awk '{ print $2; }'`
		newfs -U /dev/mirror/${gm}s${S}${P} && \
		mount    /dev/mirror/${gm}s${S}${P} /mnt${FS} && \
		dump -L -0 -f- ${FS} | (cd /mnt$FS && restore -r -v -f-)
	done
done

# crete a gmirror-aware fstab
sed -e "s;dev/${d1}s1;dev/mirror/${gm}s1;g" \
    </mnt/etc/fstab >/tmp/fstab.gmirror
sed -e "s;dev/${d1}s2;dev/mirror/${gm}s2;g" \
    </tmp/fstab.gmirror  >/mnt/etc/fstab

# load the mirro on boot
echo 'geom_mirror_load="YES"'  > /boot/loader.conf


# instruct boot stage 2 loader on first disk to boot
# with the boot stage 3 loader from the second disk
echo "1:ad(6,1,a)/boot/loader" > /boot.config

# reboot system
shutdown -r now

AND, the errors as mentioned above ...


More information about the freebsd-geom mailing list