mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 10:37:35 +03:00
Configure zed's diagnosis engine with vdev properties
Introduce four new vdev properties:
checksum_n
checksum_t
io_n
io_t
These properties can be used for configuring the thresholds of zed's
diagnosis engine and are interpeted as <N> events in T <seconds>.
When this property is set to a non-default value on a top-level vdev,
those thresholds will also apply to its leaf vdevs. This behavior can be
overridden by explicitly setting the property on the leaf vdev.
Note that, these properties do not persist across vdev replacement. For
this reason, it is advisable to set the property on the top-level vdev
instead of the leaf vdev.
The default values for zed's diagnosis engine (10 events, 600 seconds)
remains unchanged.
Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Ryan Moeller <ryan@iXsystems.com>
Reviewed-by: Allan Jude <allan@klarasystems.com>
Signed-off-by: Rob Wing <rob.wing@klarasystems.com>
Sponsored-by: Seagate Technology LLC
Closes #13805
This commit is contained in:
@@ -410,6 +410,18 @@ vdev_prop_init(void)
|
||||
sfeatures);
|
||||
|
||||
/* default numeric properties */
|
||||
zprop_register_number(VDEV_PROP_CHECKSUM_N, "checksum_n", UINT64_MAX,
|
||||
PROP_DEFAULT, ZFS_TYPE_VDEV, "<events>", "CKSUM_N", B_FALSE,
|
||||
sfeatures);
|
||||
zprop_register_number(VDEV_PROP_CHECKSUM_T, "checksum_t", UINT64_MAX,
|
||||
PROP_DEFAULT, ZFS_TYPE_VDEV, "<seconds>", "CKSUM_T", B_FALSE,
|
||||
sfeatures);
|
||||
zprop_register_number(VDEV_PROP_IO_N, "io_n", UINT64_MAX,
|
||||
PROP_DEFAULT, ZFS_TYPE_VDEV, "<events>", "IO_N", B_FALSE,
|
||||
sfeatures);
|
||||
zprop_register_number(VDEV_PROP_IO_T, "io_t", UINT64_MAX,
|
||||
PROP_DEFAULT, ZFS_TYPE_VDEV, "<seconds>", "IO_T", B_FALSE,
|
||||
sfeatures);
|
||||
|
||||
/* default index (boolean) properties */
|
||||
zprop_register_index(VDEV_PROP_REMOVING, "removing", 0,
|
||||
|
||||
+122
-15
@@ -389,6 +389,31 @@ vdev_get_nparity(vdev_t *vd)
|
||||
return (nparity);
|
||||
}
|
||||
|
||||
static int
|
||||
vdev_prop_get_int(vdev_t *vd, vdev_prop_t prop, uint64_t *value)
|
||||
{
|
||||
spa_t *spa = vd->vdev_spa;
|
||||
objset_t *mos = spa->spa_meta_objset;
|
||||
uint64_t objid;
|
||||
int err;
|
||||
|
||||
if (vd->vdev_top_zap != 0) {
|
||||
objid = vd->vdev_top_zap;
|
||||
} else if (vd->vdev_leaf_zap != 0) {
|
||||
objid = vd->vdev_leaf_zap;
|
||||
} else {
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
err = zap_lookup(mos, objid, vdev_prop_to_name(prop),
|
||||
sizeof (uint64_t), 1, value);
|
||||
|
||||
if (err == ENOENT)
|
||||
*value = vdev_prop_default_numeric(prop);
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the number of data disks for a top-level vdev.
|
||||
*/
|
||||
@@ -642,6 +667,14 @@ vdev_alloc_common(spa_t *spa, uint_t id, uint64_t guid, vdev_ops_t *ops)
|
||||
zfs_ratelimit_init(&vd->vdev_checksum_rl,
|
||||
&zfs_checksum_events_per_second, 1);
|
||||
|
||||
/*
|
||||
* Default Thresholds for tuning ZED
|
||||
*/
|
||||
vd->vdev_checksum_n = vdev_prop_default_numeric(VDEV_PROP_CHECKSUM_N);
|
||||
vd->vdev_checksum_t = vdev_prop_default_numeric(VDEV_PROP_CHECKSUM_T);
|
||||
vd->vdev_io_n = vdev_prop_default_numeric(VDEV_PROP_IO_N);
|
||||
vd->vdev_io_t = vdev_prop_default_numeric(VDEV_PROP_IO_T);
|
||||
|
||||
list_link_init(&vd->vdev_config_dirty_node);
|
||||
list_link_init(&vd->vdev_state_dirty_node);
|
||||
list_link_init(&vd->vdev_initialize_node);
|
||||
@@ -3597,6 +3630,39 @@ vdev_load(vdev_t *vd)
|
||||
}
|
||||
}
|
||||
|
||||
if (vd->vdev_top_zap != 0 || vd->vdev_leaf_zap != 0) {
|
||||
uint64_t zapobj;
|
||||
|
||||
if (vd->vdev_top_zap != 0)
|
||||
zapobj = vd->vdev_top_zap;
|
||||
else
|
||||
zapobj = vd->vdev_leaf_zap;
|
||||
|
||||
error = vdev_prop_get_int(vd, VDEV_PROP_CHECKSUM_N,
|
||||
&vd->vdev_checksum_n);
|
||||
if (error && error != ENOENT)
|
||||
vdev_dbgmsg(vd, "vdev_load: zap_lookup(zap=%llu) "
|
||||
"failed [error=%d]", (u_longlong_t)zapobj, error);
|
||||
|
||||
error = vdev_prop_get_int(vd, VDEV_PROP_CHECKSUM_T,
|
||||
&vd->vdev_checksum_t);
|
||||
if (error && error != ENOENT)
|
||||
vdev_dbgmsg(vd, "vdev_load: zap_lookup(zap=%llu) "
|
||||
"failed [error=%d]", (u_longlong_t)zapobj, error);
|
||||
|
||||
error = vdev_prop_get_int(vd, VDEV_PROP_IO_N,
|
||||
&vd->vdev_io_n);
|
||||
if (error && error != ENOENT)
|
||||
vdev_dbgmsg(vd, "vdev_load: zap_lookup(zap=%llu) "
|
||||
"failed [error=%d]", (u_longlong_t)zapobj, error);
|
||||
|
||||
error = vdev_prop_get_int(vd, VDEV_PROP_IO_T,
|
||||
&vd->vdev_io_t);
|
||||
if (error && error != ENOENT)
|
||||
vdev_dbgmsg(vd, "vdev_load: zap_lookup(zap=%llu) "
|
||||
"failed [error=%d]", (u_longlong_t)zapobj, error);
|
||||
}
|
||||
|
||||
/*
|
||||
* If this is a top-level vdev, initialize its metaslabs.
|
||||
*/
|
||||
@@ -5736,6 +5802,34 @@ vdev_prop_set(vdev_t *vd, nvlist_t *innvl, nvlist_t *outnvl)
|
||||
}
|
||||
vd->vdev_failfast = intval & 1;
|
||||
break;
|
||||
case VDEV_PROP_CHECKSUM_N:
|
||||
if (nvpair_value_uint64(elem, &intval) != 0) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
vd->vdev_checksum_n = intval;
|
||||
break;
|
||||
case VDEV_PROP_CHECKSUM_T:
|
||||
if (nvpair_value_uint64(elem, &intval) != 0) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
vd->vdev_checksum_t = intval;
|
||||
break;
|
||||
case VDEV_PROP_IO_N:
|
||||
if (nvpair_value_uint64(elem, &intval) != 0) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
vd->vdev_io_n = intval;
|
||||
break;
|
||||
case VDEV_PROP_IO_T:
|
||||
if (nvpair_value_uint64(elem, &intval) != 0) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
vd->vdev_io_t = intval;
|
||||
break;
|
||||
default:
|
||||
/* Most processing is done in vdev_props_set_sync */
|
||||
break;
|
||||
@@ -6025,28 +6119,25 @@ vdev_prop_get(vdev_t *vd, nvlist_t *innvl, nvlist_t *outnvl)
|
||||
continue;
|
||||
/* Numeric Properites */
|
||||
case VDEV_PROP_ALLOCATING:
|
||||
src = ZPROP_SRC_LOCAL;
|
||||
strval = NULL;
|
||||
|
||||
err = zap_lookup(mos, objid, nvpair_name(elem),
|
||||
sizeof (uint64_t), 1, &intval);
|
||||
if (err == ENOENT) {
|
||||
intval =
|
||||
vdev_prop_default_numeric(prop);
|
||||
err = 0;
|
||||
} else if (err)
|
||||
break;
|
||||
if (intval == vdev_prop_default_numeric(prop))
|
||||
src = ZPROP_SRC_DEFAULT;
|
||||
|
||||
/* Leaf vdevs cannot have this property */
|
||||
if (vd->vdev_mg == NULL &&
|
||||
vd->vdev_top != NULL) {
|
||||
src = ZPROP_SRC_NONE;
|
||||
intval = ZPROP_BOOLEAN_NA;
|
||||
} else {
|
||||
err = vdev_prop_get_int(vd, prop,
|
||||
&intval);
|
||||
if (err && err != ENOENT)
|
||||
break;
|
||||
|
||||
if (intval ==
|
||||
vdev_prop_default_numeric(prop))
|
||||
src = ZPROP_SRC_DEFAULT;
|
||||
else
|
||||
src = ZPROP_SRC_LOCAL;
|
||||
}
|
||||
|
||||
vdev_prop_add_list(outnvl, propname, strval,
|
||||
vdev_prop_add_list(outnvl, propname, NULL,
|
||||
intval, src);
|
||||
break;
|
||||
case VDEV_PROP_FAILFAST:
|
||||
@@ -6068,6 +6159,22 @@ vdev_prop_get(vdev_t *vd, nvlist_t *innvl, nvlist_t *outnvl)
|
||||
vdev_prop_add_list(outnvl, propname, strval,
|
||||
intval, src);
|
||||
break;
|
||||
case VDEV_PROP_CHECKSUM_N:
|
||||
case VDEV_PROP_CHECKSUM_T:
|
||||
case VDEV_PROP_IO_N:
|
||||
case VDEV_PROP_IO_T:
|
||||
err = vdev_prop_get_int(vd, prop, &intval);
|
||||
if (err && err != ENOENT)
|
||||
break;
|
||||
|
||||
if (intval == vdev_prop_default_numeric(prop))
|
||||
src = ZPROP_SRC_DEFAULT;
|
||||
else
|
||||
src = ZPROP_SRC_LOCAL;
|
||||
|
||||
vdev_prop_add_list(outnvl, propname, NULL,
|
||||
intval, src);
|
||||
break;
|
||||
/* Text Properties */
|
||||
case VDEV_PROP_COMMENT:
|
||||
/* Exists in the ZAP below */
|
||||
|
||||
@@ -200,6 +200,42 @@ recent_events_compare(const void *a, const void *b)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* workaround: vdev properties don't have inheritance
|
||||
*/
|
||||
static uint64_t
|
||||
vdev_prop_get_inherited(vdev_t *vd, vdev_prop_t prop)
|
||||
{
|
||||
uint64_t propdef, propval;
|
||||
|
||||
propdef = vdev_prop_default_numeric(prop);
|
||||
switch (prop) {
|
||||
case VDEV_PROP_CHECKSUM_N:
|
||||
propval = vd->vdev_checksum_n;
|
||||
break;
|
||||
case VDEV_PROP_CHECKSUM_T:
|
||||
propval = vd->vdev_checksum_t;
|
||||
break;
|
||||
case VDEV_PROP_IO_N:
|
||||
propval = vd->vdev_io_n;
|
||||
break;
|
||||
case VDEV_PROP_IO_T:
|
||||
propval = vd->vdev_io_t;
|
||||
break;
|
||||
default:
|
||||
propval = propdef;
|
||||
break;
|
||||
}
|
||||
|
||||
if (propval != propdef)
|
||||
return (propval);
|
||||
|
||||
if (vd->vdev_parent == NULL)
|
||||
return (propdef);
|
||||
|
||||
return (vdev_prop_get_inherited(vd->vdev_parent, prop));
|
||||
}
|
||||
|
||||
static void zfs_ereport_schedule_cleaner(void);
|
||||
|
||||
/*
|
||||
@@ -662,6 +698,49 @@ zfs_ereport_start(nvlist_t **ereport_out, nvlist_t **detector_out,
|
||||
DATA_TYPE_UINT64, zb->zb_blkid, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Payload for tuning the zed
|
||||
*/
|
||||
if (vd != NULL && strcmp(subclass, FM_EREPORT_ZFS_CHECKSUM) == 0) {
|
||||
uint64_t cksum_n, cksum_t;
|
||||
|
||||
cksum_n = vdev_prop_get_inherited(vd, VDEV_PROP_CHECKSUM_N);
|
||||
if (cksum_n != vdev_prop_default_numeric(VDEV_PROP_CHECKSUM_N))
|
||||
fm_payload_set(ereport,
|
||||
FM_EREPORT_PAYLOAD_ZFS_VDEV_CKSUM_N,
|
||||
DATA_TYPE_UINT64,
|
||||
cksum_n,
|
||||
NULL);
|
||||
|
||||
cksum_t = vdev_prop_get_inherited(vd, VDEV_PROP_CHECKSUM_T);
|
||||
if (cksum_t != vdev_prop_default_numeric(VDEV_PROP_CHECKSUM_T))
|
||||
fm_payload_set(ereport,
|
||||
FM_EREPORT_PAYLOAD_ZFS_VDEV_CKSUM_T,
|
||||
DATA_TYPE_UINT64,
|
||||
cksum_t,
|
||||
NULL);
|
||||
}
|
||||
|
||||
if (vd != NULL && strcmp(subclass, FM_EREPORT_ZFS_IO) == 0) {
|
||||
uint64_t io_n, io_t;
|
||||
|
||||
io_n = vdev_prop_get_inherited(vd, VDEV_PROP_IO_N);
|
||||
if (io_n != vdev_prop_default_numeric(VDEV_PROP_IO_N))
|
||||
fm_payload_set(ereport,
|
||||
FM_EREPORT_PAYLOAD_ZFS_VDEV_IO_N,
|
||||
DATA_TYPE_UINT64,
|
||||
io_n,
|
||||
NULL);
|
||||
|
||||
io_t = vdev_prop_get_inherited(vd, VDEV_PROP_IO_T);
|
||||
if (io_t != vdev_prop_default_numeric(VDEV_PROP_IO_T))
|
||||
fm_payload_set(ereport,
|
||||
FM_EREPORT_PAYLOAD_ZFS_VDEV_IO_T,
|
||||
DATA_TYPE_UINT64,
|
||||
io_t,
|
||||
NULL);
|
||||
}
|
||||
|
||||
mutex_exit(&spa->spa_errlist_lock);
|
||||
|
||||
*ereport_out = ereport;
|
||||
|
||||
Reference in New Issue
Block a user