zfs_fm.c revision c3c6d682c37d74c66eaa34c4ed6c91a65f83d89d
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/spa_impl.h>
#include <sys/vdev_impl.h>
#include <sys/sysevent.h>
/*
* This general routine is responsible for generating all the different ZFS
* ereports. The payload is dependent on the class, and which arguments are
* supplied to the function:
*
* EREPORT POOL VDEV IO
* block X X X
* data X X
* device X X
* pool X
*
* If we are in a loading state, all errors are chained together by the same
* SPA-wide ENA.
*
* For isolated I/O requests, we get the ENA from the zio_t. The propagation
* gets very complicated due to RAID-Z, gang blocks, and vdev caching. We want
* to chain together all ereports associated with a logical piece of data. For
* layered diagram:
*
* +---------------+
* | Aggregate I/O | No associated logical data or device
* +---------------+
* |
* V
* +---------------+ Reads associated with a piece of logical data.
* | Read I/O | This includes reads on behalf of RAID-Z,
* +---------------+ mirrors, gang blocks, retries, etc.
* |
* V
* +---------------+ Reads associated with a particular device, but
* | Physical I/O | no logical data. Issued as part of vdev caching
* +---------------+ and I/O aggregation.
*
* Note that 'physical I/O' here is not the same terminology as used in the rest
* of ZIO. Typically, 'physical I/O' simply means that there is no attached
* blockpointer. But I/O with no associated block pointer can still be related
* to a logical piece of data (i.e. RAID-Z requests).
*
* Purely physical I/O always have unique ENAs. They are not related to a
* particular piece of logical data, and therefore cannot be chained together.
* We still generate an ereport, but the DE doesn't correlate it with any
* logical piece of data. When such an I/O fails, the delegated I/O requests
* will issue a retry, which will trigger the 'real' ereport with the correct
* ENA.
*
* We keep track of the ENA for a ZIO chain through the 'io_logical' member.
* then inherit this pointer, so that when it is first set subsequent failures
* will use the same ENA. If a physical I/O is issued (by passing the
* ZIO_FLAG_NOBOOKMARK flag), then this pointer is reset, guaranteeing that a
* unique ENA will be generated. For an aggregate I/O, this pointer is set to
* NULL, and no ereport will be generated (since it doesn't actually correspond
* to any particular device or piece of data).
*/
void
{
#ifdef _KERNEL
char class[64];
/*
* If we are doing a spa_tryimport(), ignore errors.
*/
return;
/*
* If we are in the middle of opening a pool, and the previous attempt
* failed, don't bother logging any new ereports - we're just going to
* get the same diagnosis anyway.
*/
return;
/*
* only generate errors from the final failure.
*/
return;
/*
* If this is not a read or write zio, ignore the error. This can occur
* if the DKIOCFLUSHWRITECACHE ioctl fails.
*/
return;
return;
return;
}
/*
* Serialize ereport generation
*/
/*
* Determine the ENA to use for this event. If we are in a loading
* state, use a SPA-wide ENA. Otherwise, if we are in an I/O state, use
* a root zio-wide ENA. Otherwise, simply use a unique ENA.
*/
} else {
}
/*
* Construct the full class, detector, and other standard FMA fields.
*/
/*
* Construct the per-ereport payload, depending on which parameters are
* passed in.
*/
/*
* Generic payload members common to all ereports.
*
* The direct reference to spa_name is used rather than spa_name()
* because of the asynchronous nature of the zio pipeline. spa_name()
* asserts that the config lock is held in some form. This is always
* the case in I/O context, but because the check for RW_WRITER compares
* against 'curthread', we may be in an asynchronous context and blow
* this assert. Rather than loosen this assert, we acknowledge that all
* contexts in which this function is called (pool open, I/O) are safe,
* and dereference the name directly.
*/
if (vd->vdev_devid)
NULL);
if (pvd->vdev_devid)
}
}
/*
*/
/*
* If the 'size' parameter is non-zero, it indicates this is a
* RAID-Z or other I/O where the physical offset and length are
* provided for us, instead of within the zio_t.
*/
if (size)
else
}
/*
*/
/*
* If we have a vdev but no zio, this is a device fault, and the
* 'stateoroffset' parameter indicates the previous state of the
* vdev.
*/
}
#endif
}
/*
* The 'resource.fs.zfs.ok' event is an internal signal that the associated
* resource (pool or disk) has been identified by ZFS as healthy. This will
* then trigger the DE to close the associated case, if any.
*/
void
{
#ifdef _KERNEL
char class[64];
return;
if (vd)
#endif
}