Mercurial > illumos > illumos-gate
changeset 7041:b4c5fe87fad8
6721901 uninitialized variable in zfs_fm_recv() can confuse diagnosis
6721906 probe failure should be ignored during pool open
6721920 cache device failure should not trigger pool I/O failure
6722096 ZFS DE case clearing logic for vdevs is busted
6722098 ZFS DE should avoid ereports against non-leaf vdevs
6722100 replacing a hot spare with an idle spare doesn't work
author | eschrock |
---|---|
date | Fri, 04 Jul 2008 13:08:26 -0700 |
parents | eeae3015c35e |
children | 46fc4b6db23e |
files | usr/src/cmd/fm/modules/common/zfs-diagnosis/zfs_de.c usr/src/lib/libzfs/common/libzfs_pool.c usr/src/uts/common/fs/zfs/vdev_label.c |
diffstat | 3 files changed, 46 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/cmd/fm/modules/common/zfs-diagnosis/zfs_de.c Fri Jul 04 06:02:33 2008 -0700 +++ b/usr/src/cmd/fm/modules/common/zfs-diagnosis/zfs_de.c Fri Jul 04 13:08:26 2008 -0700 @@ -166,7 +166,19 @@ * Iterate over all children. */ if (nvlist_lookup_nvlist_array(vd, ZPOOL_CONFIG_CHILDREN, &child, - &children) != 0) { + &children) == 0) { + for (c = 0; c < children; c++) + zfs_mark_vdev(pool_guid, child[c]); + } + + if (nvlist_lookup_nvlist_array(vd, ZPOOL_CONFIG_L2CACHE, &child, + &children) == 0) { + for (c = 0; c < children; c++) + zfs_mark_vdev(pool_guid, child[c]); + } + + if (nvlist_lookup_nvlist_array(vd, ZPOOL_CONFIG_SPARES, &child, + &children) == 0) { for (c = 0; c < children; c++) zfs_mark_vdev(pool_guid, child[c]); } @@ -341,7 +353,7 @@ uint64_t ena, pool_guid, vdev_guid; nvlist_t *detector; boolean_t isresource; - boolean_t checkremove; + char *type; isresource = fmd_nvl_class_match(hdl, nvl, "resource.fs.zfs.*"); @@ -375,11 +387,25 @@ * Device I/O errors are ignored during pool open. */ if (pool_state == SPA_LOAD_OPEN && - (fmd_nvl_class_match(hdl, nvl, "ereport.fs.zfs.checksum") || - fmd_nvl_class_match(hdl, nvl, "ereport.fs.zfs.io"))) + (fmd_nvl_class_match(hdl, nvl, + ZFS_MAKE_EREPORT(FM_EREPORT_ZFS_CHECKSUM)) || + fmd_nvl_class_match(hdl, nvl, + ZFS_MAKE_EREPORT(FM_EREPORT_ZFS_IO)) || + fmd_nvl_class_match(hdl, nvl, + ZFS_MAKE_EREPORT(FM_EREPORT_ZFS_PROBE_FAILURE)))) return; /* + * We ignore ereports for anything except disks and files. + */ + if (nvlist_lookup_string(nvl, FM_EREPORT_PAYLOAD_ZFS_VDEV_TYPE, + &type) == 0) { + if (strcmp(type, VDEV_TYPE_DISK) != 0 && + strcmp(type, VDEV_TYPE_FILE) != 0) + return; + } + + /* * Determine if this ereport corresponds to an open case. Cases are * indexed by ENA, since ZFS does all the work of chaining together * related ereports. @@ -555,6 +581,7 @@ fmd_nvl_class_match(hdl, nvl, ZFS_MAKE_EREPORT(FM_EREPORT_ZFS_PROBE_FAILURE))) { char *failmode = NULL; + boolean_t checkremove = B_FALSE; /* * If this is a checksum or I/O error, then toss it into the
--- a/usr/src/lib/libzfs/common/libzfs_pool.c Fri Jul 04 06:02:33 2008 -0700 +++ b/usr/src/lib/libzfs/common/libzfs_pool.c Fri Jul 04 13:08:26 2008 -0700 @@ -1502,7 +1502,7 @@ nvlist_t *tgt; boolean_t avail_spare, l2cache; uint64_t val, is_log; - char *path; + char *path, *newname; nvlist_t **child; uint_t children; nvlist_t *config_root; @@ -1538,17 +1538,20 @@ verify(nvlist_lookup_nvlist(zpool_get_config(zhp, NULL), ZPOOL_CONFIG_VDEV_TREE, &config_root) == 0); + if ((newname = zpool_vdev_name(NULL, NULL, child[0])) == NULL) + return (-1); + /* * If the target is a hot spare that has been swapped in, we can only * replace it with another hot spare. */ if (replacing && nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_IS_SPARE, &val) == 0 && - nvlist_lookup_string(child[0], ZPOOL_CONFIG_PATH, &path) == 0 && - (zpool_find_vdev(zhp, path, &avail_spare, &l2cache) == NULL || + (zpool_find_vdev(zhp, newname, &avail_spare, &l2cache) == NULL || !avail_spare) && is_replacing_spare(config_root, tgt, 1)) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "can only be replaced by another hot spare")); + free(newname); return (zfs_error(hdl, EZFS_BADTARGET, msg)); } @@ -1558,13 +1561,16 @@ */ if (replacing && nvlist_lookup_string(child[0], ZPOOL_CONFIG_PATH, &path) == 0 && - zpool_find_vdev(zhp, path, &avail_spare, &l2cache) != NULL && + zpool_find_vdev(zhp, newname, &avail_spare, &l2cache) != NULL && avail_spare && is_replacing_spare(config_root, tgt, 0)) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "device has already been replaced with a spare")); + free(newname); return (zfs_error(hdl, EZFS_BADTARGET, msg)); } + free(newname); + if (zcmd_write_conf_nvlist(hdl, &zc, nvroot) != 0) return (-1);
--- a/usr/src/uts/common/fs/zfs/vdev_label.c Fri Jul 04 06:02:33 2008 -0700 +++ b/usr/src/uts/common/fs/zfs/vdev_label.c Fri Jul 04 13:08:26 2008 -0700 @@ -913,10 +913,10 @@ } /* - * We ignore errors for log devices, simply free the private data. + * We ignore errors for log and cache devices, simply free the private data. */ static void -vdev_label_sync_log_done(zio_t *zio) +vdev_label_sync_ignore_done(zio_t *zio) { kmem_free(zio->io_private, sizeof (uint64_t)); } @@ -993,8 +993,9 @@ for (vd = list_head(dl); vd != NULL; vd = list_next(dl, vd)) { uint64_t *good_writes = kmem_zalloc(sizeof (uint64_t), KM_SLEEP); - zio_t *vio = zio_null(nio, spa, vd->vdev_islog ? - vdev_label_sync_log_done : vdev_label_sync_top_done, + zio_t *vio = zio_null(nio, spa, + (vd->vdev_islog || vd->vdev_aux != NULL) ? + vdev_label_sync_ignore_done : vdev_label_sync_top_done, good_writes, flags); vdev_label_sync(vio, vd, l, txg); zio_nowait(vio);