410 is_repair = B_FALSE;
411
412 /*
413 * We subscribe to zfs faults as well as all repair events.
414 */
415 if (nvlist_lookup_nvlist_array(nvl, FM_SUSPECT_FAULT_LIST,
416 &faults, &nfaults) != 0)
417 return;
418
419 for (f = 0; f < nfaults; f++) {
420 fault = faults[f];
421
422 fault_device = B_FALSE;
423 degrade_device = B_FALSE;
424 is_disk = B_FALSE;
425
426 if (nvlist_lookup_boolean_value(fault, FM_SUSPECT_RETIRE,
427 &retire) == 0 && retire == 0)
428 continue;
429
430 /*
431 * While we subscribe to fault.fs.zfs.*, we only take action
432 * for faults targeting a specific vdev (open failure or SERD
433 * failure). We also subscribe to fault.io.* events, so that
434 * faulty disks will be faulted in the ZFS configuration.
435 */
436 if (fmd_nvl_class_match(hdl, fault, "fault.fs.zfs.vdev.io")) {
437 fault_device = B_TRUE;
438 } else if (fmd_nvl_class_match(hdl, fault,
439 "fault.fs.zfs.vdev.checksum")) {
440 degrade_device = B_TRUE;
441 } else if (fmd_nvl_class_match(hdl, fault,
442 "fault.fs.zfs.device")) {
443 fault_device = B_FALSE;
444 } else if (fmd_nvl_class_match(hdl, fault, "fault.io.*")) {
445 is_disk = B_TRUE;
446 fault_device = B_TRUE;
447 } else {
448 continue;
449 }
544 */
545 replace_with_spare(hdl, zhp, vdev);
546 zpool_close(zhp);
547 }
548
549 if (strcmp(class, FM_LIST_REPAIRED_CLASS) == 0 && repair_done &&
550 nvlist_lookup_string(nvl, FM_SUSPECT_UUID, &uuid) == 0)
551 fmd_case_uuresolved(hdl, uuid);
552 }
553
554 static const fmd_hdl_ops_t fmd_ops = {
555 zfs_retire_recv, /* fmdo_recv */
556 NULL, /* fmdo_timeout */
557 NULL, /* fmdo_close */
558 NULL, /* fmdo_stats */
559 NULL, /* fmdo_gc */
560 };
561
562 static const fmd_prop_t fmd_props[] = {
563 { "spare_on_remove", FMD_TYPE_BOOL, "true" },
564 { NULL, 0, NULL }
565 };
566
567 static const fmd_hdl_info_t fmd_info = {
568 "ZFS Retire Agent", "1.0", &fmd_ops, fmd_props
569 };
570
571 void
572 _fmd_init(fmd_hdl_t *hdl)
573 {
574 zfs_retire_data_t *zdp;
575 libzfs_handle_t *zhdl;
576
577 if ((zhdl = libzfs_init()) == NULL)
578 return;
579
580 if (fmd_hdl_register(hdl, FMD_API_VERSION, &fmd_info) != 0) {
581 libzfs_fini(zhdl);
582 return;
583 }
|
410 is_repair = B_FALSE;
411
412 /*
413 * We subscribe to zfs faults as well as all repair events.
414 */
415 if (nvlist_lookup_nvlist_array(nvl, FM_SUSPECT_FAULT_LIST,
416 &faults, &nfaults) != 0)
417 return;
418
419 for (f = 0; f < nfaults; f++) {
420 fault = faults[f];
421
422 fault_device = B_FALSE;
423 degrade_device = B_FALSE;
424 is_disk = B_FALSE;
425
426 if (nvlist_lookup_boolean_value(fault, FM_SUSPECT_RETIRE,
427 &retire) == 0 && retire == 0)
428 continue;
429
430 if (fmd_nvl_class_match(hdl, fault,
431 "fault.io.disk.ssm-wearout") &&
432 fmd_prop_get_int32(hdl, "ssm_wearout_skip_retire") ==
433 FMD_B_TRUE) {
434 fmd_hdl_debug(hdl, "zfs-retire: ignoring SSM fault");
435 continue;
436 }
437
438 /*
439 * While we subscribe to fault.fs.zfs.*, we only take action
440 * for faults targeting a specific vdev (open failure or SERD
441 * failure). We also subscribe to fault.io.* events, so that
442 * faulty disks will be faulted in the ZFS configuration.
443 */
444 if (fmd_nvl_class_match(hdl, fault, "fault.fs.zfs.vdev.io")) {
445 fault_device = B_TRUE;
446 } else if (fmd_nvl_class_match(hdl, fault,
447 "fault.fs.zfs.vdev.checksum")) {
448 degrade_device = B_TRUE;
449 } else if (fmd_nvl_class_match(hdl, fault,
450 "fault.fs.zfs.device")) {
451 fault_device = B_FALSE;
452 } else if (fmd_nvl_class_match(hdl, fault, "fault.io.*")) {
453 is_disk = B_TRUE;
454 fault_device = B_TRUE;
455 } else {
456 continue;
457 }
552 */
553 replace_with_spare(hdl, zhp, vdev);
554 zpool_close(zhp);
555 }
556
557 if (strcmp(class, FM_LIST_REPAIRED_CLASS) == 0 && repair_done &&
558 nvlist_lookup_string(nvl, FM_SUSPECT_UUID, &uuid) == 0)
559 fmd_case_uuresolved(hdl, uuid);
560 }
561
562 static const fmd_hdl_ops_t fmd_ops = {
563 zfs_retire_recv, /* fmdo_recv */
564 NULL, /* fmdo_timeout */
565 NULL, /* fmdo_close */
566 NULL, /* fmdo_stats */
567 NULL, /* fmdo_gc */
568 };
569
570 static const fmd_prop_t fmd_props[] = {
571 { "spare_on_remove", FMD_TYPE_BOOL, "true" },
572 { "ssm_wearout_skip_retire", FMD_TYPE_BOOL, "true"},
573 { NULL, 0, NULL }
574 };
575
576 static const fmd_hdl_info_t fmd_info = {
577 "ZFS Retire Agent", "1.0", &fmd_ops, fmd_props
578 };
579
580 void
581 _fmd_init(fmd_hdl_t *hdl)
582 {
583 zfs_retire_data_t *zdp;
584 libzfs_handle_t *zhdl;
585
586 if ((zhdl = libzfs_init()) == NULL)
587 return;
588
589 if (fmd_hdl_register(hdl, FMD_API_VERSION, &fmd_info) != 0) {
590 libzfs_fini(zhdl);
591 return;
592 }
|