The major change here is to fix up libefi to be linux aware. For
the most part this wasn't too hard but there were a few major issues.
First off I needed to handle the DKIOCGMEDIAINFO and DKIOCINFO ioctls.
There is no direct equivilant for these ioctls under linux. To handle
this I added wrapper functions which under Solaris simple call the ioctls.
But under Linux dig around the system a little bit getting the needed
info to fill in the requested structures.
Secondly the efi_ioctl() call was adapted such that under linux it directly
read or writes out the partition table. Under Solaris this work was
handed off to the kernel via an ioctl. In the efi_write() case we also
ensure we prompt the kernel via BLKRRPART to re-scan the new partition
table. The libefi generated partition tables are correct but older
versions of ~parted-1.8.1 can not read them without a small patch.
The kernel and fdisk are able to read them just fine.
Thirdly efi_alloc_and_init() which is used by zpool to determine if a
device is a 'wholedisk' was updated to be linux aware. This check is
performed by using the partition number for the device, which the
partition number is 0 on linux it is a 'wholedisk'. However, certain
device type such as the loopback and ram disks needed to be excluded
because they do not support partitioning.
Forthly the zpool command was made symlink aware so it can correctly
resolve udev entries such as /dev/disk/by-*/*. This symlinks are
fully expanded ensuring all block devices are recognized. When a
when a 'wholedisk' block device is detected we now properly write
out an efi label and place zfs in the first partition (0th slice).
This partition is created 1MiB in to the disk to ensure it is aligned
nicely with all high end block devices I'm aware of.
This all works for me now but it did take quite a bit of work to get
it all sorted out. It would not surprise me if certain special cases
were missed so we should keep any eye of for any odd behavior.
Because the local 'index' variable shadows the index() function
it was replaced by 'i'. Unfortunately when I made this change
I accidentally replaced one instance with 'j' resulting in the
short decimal values being printed incorrectly.
It's still not clear to me why the default value here is large
enough Solaris. I hit this limit again when setting up 120 SATA
drives configured as 15 raidz2 groups each containing 8 drives.
We expect to go bigger so we may just want to spend a little
time and figure out how to make this all dynamic.