mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 10:37:35 +03:00
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:
committed by
Brian Behlendorf
parent
0b284702b7
commit
d02ca37979
+14
-13
@@ -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
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user