zfsonlinux / pkg-zfs

Native ZFS packaging for Debian and Ubuntu
https://launchpad.net/~zfs-native/+archive/daily
308 stars 55 forks source link

os-prober test for zvols is incorrect #193

Open waddles opened 8 years ago

waddles commented 8 years ago

62 fix depends on the major device type in hex being 'e6' which is not always true for zfs devices.

My system uses major devices 8, 65, 66 (ie. 0x8, 0x41, 0x42) for my zpool vdevs, therefore that test never passes and os-prober always tries to mount the vdevs every time grub-mkconfig runs. I'm using Ubuntu Vivid (15.04) and this may be the root cause of a problem with locking up I/O on the zpool during unattended upgrades.

The problem is actually in os-prober's fs_type function that fails to detect that a partition is a zfs_member partition. Eg. all of my JBOD disks from sda to sdag are vdevs; sdah is a RAID using a physical controller which contains the OS volumes on LVM and the slog device on sdah6.

# . /usr/share/os-prober/common.sh          <-- contains fs_type()
# for partition in /dev/sd*; do echo "$partition : $(fs_type $partition)"; done
/dev/sda :
/dev/sda1 :
/dev/sda9 :
/dev/sdaa :
/dev/sdaa1 : zfs_member
/dev/sdaa9 :
/dev/sdab :
/dev/sdab1 : zfs_member
...
/dev/sdag9 :
/dev/sdah :
/dev/sdah1 : ext4
/dev/sdah2 :
/dev/sdah5 : LVM2_member
/dev/sdah6 : zfs_member
/dev/sdb :
/dev/sdb1 : zfs_member
/dev/sdb9 :
/dev/sdc :
...

Ideally this should be fixed upstream in os-prober so it skips any zfs partitions but that probably won't happen until zfsonlinux is included in Ubuntu's universe, so in the mean time as a workaround, I am using this modified test that checks if the partition is part of a vdev by checking the /etc/zfs/vdev_ids.conf file and resolving them to a parent disk device.

It probably doesn't work for all disk names and/or vdev aliases so I am happy for someone to suggest a better solution.

#!/bin/sh
# Sub-test to exclude ZVOLs
set -e
partition="$1"

. /usr/share/os-prober/common.sh

#if [ "$(stat -L -c %t "$partition")" = "e6" ] ; then
parent="$(echo $partition | sed -e 's/[0-9]$//')"
if (for path in $(awk '/^alias/ {print $3}' /etc/zfs/vdev_id.conf); do readlink -f $path; done | grep -Fqw "$parent"); then
    debug "$partition is a ZVOL; skipping"
    exit 0
fi

# No ZVOLs found
exit 1