K 10 svn:author V 7 asomers K 8 svn:date V 27 2013-10-14T23:31:18.240128Z K 7 svn:log V 2617 Improve zfsd's spare handling. Zfsd can now: - Spare broken spares, whether a case file is created for the original drive or for the previous spare. - Avoid sparing spares that are either resilvering or healthy. This enables failover of multiple devices in a pool. It also means that zfsd doesn't require more spares than are actually needed to make a pool whole again. cddl/sbin/zfsd/vdev.h: cddl/sbin/zfsd/vdev.cc: - Add NonexistentVdev, a singleton instance of Vdev that represents a vdev that doesn't exist. Supporting this are new methods: - Vdev::Vdev(), an empty copy constructor. - Vdev::DoesNotExist(), which returns true if the vdev doesn't exist. - Add vdev tree methods of use for purposes for which VdevIterator is not appropriate: - Vdev::Children(), which returns a list of the vdev's children. - Vdev::RootVdev(), which returns the root vdev of the vdev's pool. - Vdev::Parent(), which returns the vdev's parent. This works by traversing the tree until it finds a vdev whose children include the caller object. - Add several useful vdev instance methods: - Vdev::IsAvailableSpare(), which returns whether the vdev is an unassigned and usable spare. - Vdev::Name(), which returns the vdev's name; it can be made to return a "verbose" name too (e.g. "spare" vs. "spare-1"). - Vdev::IsSpare(), Vdev::IsActiveSpare(), and Vdev::IsResilvering(). - While I'm here, refactor Vdev::Vdev(*) so that common initialization code only exists in one place. cddl/sbin/zfsd/case_file.h: cddl/sbin/zfsd/case_file.cc: - Add CaseFile::BeingReplacedBy(), which returns the device replacing the current device, if one exists. Performing this requires finding the vdev's parent and checking the state of its children. - Change CaseFile::Replace() to allow the caller to specify whether the case's vdev is being replaced by a spare. This enables Replace() to detect the appropriate device to perform the actual replace on. - Add CaseFile::CaseVdev() to obtain a Vdev for the case file, and use it in several places that perform the operation. cddl/sbin/zfsd/case_file.cc: - Improve logging for case file evaluation so that the action chosen is always logged. - While I'm here, make zpool lookups consistent and always generate a zpool_handle_t * local to the function where it's needed. cddl/sbin/zfsd/vdev.h: cddl/sbin/zfsd/zfsd_exception.cc: - Add , now required because of Vdev::Children() in vdev.h. Submitted by: will Approved by: ken (mentor) Sponsored by: Spectra Logic Corporation END