Bring over illumos ZFS FMA logic -- phase 1

This first phase brings over the ZFS SLM module, zfs_mod.c, to handle
auto operations in response to disk events. Disk event monitoring is
provided from libudev and generates the expected payload schema for
zfs_mod. This work leverages the recently added devid and phys_path
strings in the vdev label.

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Don Brady <don.brady@intel.com>
Signed-off-by: Tony Hutter <hutter2@llnl.gov>
Closes #4673
This commit is contained in:
Don Brady
2016-08-31 15:46:58 -06:00
committed by Brian Behlendorf
parent 0b284702b7
commit d02ca37979
20 changed files with 1837 additions and 39 deletions
+14 -13
View File
@@ -3373,19 +3373,6 @@ vdev_set_state(vdev_t *vd, boolean_t isopen, vdev_state_t state, vdev_aux_t aux)
vd->vdev_ops->vdev_op_leaf)
vd->vdev_ops->vdev_op_close(vd);
/*
* If we have brought this vdev back into service, we need
* to notify fmd so that it can gracefully repair any outstanding
* cases due to a missing device. We do this in all cases, even those
* that probably don't correlate to a repaired fault. This is sure to
* catch all cases, and we let the zfs-retire agent sort it out. If
* this is a transient state it's OK, as the retire agent will
* double-check the state of the vdev before repairing it.
*/
if (state == VDEV_STATE_HEALTHY && vd->vdev_ops->vdev_op_leaf &&
vd->vdev_prevstate != state)
zfs_post_state_change(spa, vd);
if (vd->vdev_removed &&
state == VDEV_STATE_CANT_OPEN &&
(aux == VDEV_AUX_OPEN_FAILED || vd->vdev_checkremove)) {
@@ -3466,6 +3453,20 @@ vdev_set_state(vdev_t *vd, boolean_t isopen, vdev_state_t state, vdev_aux_t aux)
vd->vdev_removed = B_FALSE;
}
/*
* Notify ZED of any significant state-change on a leaf vdev.
*
* We ignore transitions from a closed state to healthy unless
* the parent was degraded.
*/
if (vd->vdev_ops->vdev_op_leaf &&
((save_state > VDEV_STATE_CLOSED) ||
(vd->vdev_state < VDEV_STATE_HEALTHY) ||
(vd->vdev_parent != NULL &&
vd->vdev_parent->vdev_prevstate == VDEV_STATE_DEGRADED))) {
zfs_post_state_change(spa, vd, save_state);
}
if (!isopen && vd->vdev_parent)
vdev_propagate_state(vd->vdev_parent);
}
+36 -6
View File
@@ -848,7 +848,8 @@ zfs_ereport_post_checksum(spa_t *spa, vdev_t *vd,
}
static void
zfs_post_common(spa_t *spa, vdev_t *vd, const char *type, const char *name)
zfs_post_common(spa_t *spa, vdev_t *vd, const char *type, const char *name,
nvlist_t *aux)
{
#ifdef _KERNEL
nvlist_t *resource;
@@ -883,6 +884,13 @@ zfs_post_common(spa_t *spa, vdev_t *vd, const char *type, const char *name)
if (vd->vdev_fru != NULL)
VERIFY0(nvlist_add_string(resource,
FM_EREPORT_PAYLOAD_ZFS_VDEV_FRU, vd->vdev_fru));
/* also copy any optional payload data */
if (aux) {
nvpair_t *elem = NULL;
while ((elem = nvlist_next_nvpair(aux, elem)) != NULL)
(void) nvlist_add_nvpair(resource, elem);
}
}
zfs_zevent_post(resource, NULL, zfs_zevent_post_cb);
@@ -898,7 +906,7 @@ zfs_post_common(spa_t *spa, vdev_t *vd, const char *type, const char *name)
void
zfs_post_remove(spa_t *spa, vdev_t *vd)
{
zfs_post_common(spa, vd, FM_RSRC_CLASS, FM_RESOURCE_REMOVED);
zfs_post_common(spa, vd, FM_RSRC_CLASS, FM_RESOURCE_REMOVED, NULL);
}
/*
@@ -909,7 +917,7 @@ zfs_post_remove(spa_t *spa, vdev_t *vd)
void
zfs_post_autoreplace(spa_t *spa, vdev_t *vd)
{
zfs_post_common(spa, vd, FM_RSRC_CLASS, FM_RESOURCE_AUTOREPLACE);
zfs_post_common(spa, vd, FM_RSRC_CLASS, FM_RESOURCE_AUTOREPLACE, NULL);
}
/*
@@ -919,9 +927,31 @@ zfs_post_autoreplace(spa_t *spa, vdev_t *vd)
* open because the device was not found (fault.fs.zfs.device).
*/
void
zfs_post_state_change(spa_t *spa, vdev_t *vd)
zfs_post_state_change(spa_t *spa, vdev_t *vd, uint64_t laststate)
{
zfs_post_common(spa, vd, FM_RSRC_CLASS, FM_RESOURCE_STATECHANGE);
#ifdef _KERNEL
nvlist_t *aux;
/*
* Add optional supplemental keys to payload
*/
aux = fm_nvlist_create(NULL);
if (vd && aux) {
if (vd->vdev_physpath) {
(void) nvlist_add_string(aux,
FM_EREPORT_PAYLOAD_ZFS_VDEV_PHYSPATH,
vd->vdev_physpath);
}
(void) nvlist_add_uint64(aux,
FM_EREPORT_PAYLOAD_ZFS_VDEV_LASTSTATE, laststate);
}
zfs_post_common(spa, vd, FM_RSRC_CLASS, FM_RESOURCE_STATECHANGE,
aux);
if (aux)
fm_nvlist_destroy(aux, FM_NVA_FREE);
#endif
}
/*
@@ -933,7 +963,7 @@ zfs_post_state_change(spa_t *spa, vdev_t *vd)
void
zfs_post_sysevent(spa_t *spa, vdev_t *vd, const char *name)
{
zfs_post_common(spa, vd, FM_SYSEVENT_CLASS, name);
zfs_post_common(spa, vd, FM_SYSEVENT_CLASS, name, NULL);
}
#if defined(_KERNEL) && defined(HAVE_SPL)