#include <sys/zfs_ioctl.h>
#include <time.h>
#include <unistd.h>
+#include <sys/fm/fs/zfs.h>
#include "zed.h"
#include "zed_conf.h"
+#include "zed_disk_event.h"
#include "zed_exec.h"
#include "zed_file.h"
#include "zed_log.h"
#include "zed_strings.h"
+#include "agents/zfs_agents.h"
+
#define MAXBUF 4096
/*
if (zcp->zevent_fd < 0)
zed_log_die("Failed to open \"%s\": %s",
ZFS_DEV, strerror(errno));
+
+ zfs_agent_init(zcp->zfs_hdl);
+
+ if (zed_disk_event_init() != 0)
+ zed_log_die("Failed to initialize disk events");
}
/*
if (!zcp)
zed_log_die("Failed zed_event_fini: %s", strerror(EINVAL));
+ zed_disk_event_fini();
+ zfs_agent_fini();
+
if (zcp->zevent_fd >= 0) {
if (close(zcp->zevent_fd) < 0)
zed_log_msg(LOG_WARNING, "Failed to close \"%s\": %s",
*dstp++ = '=';
buflen--;
+ if (buflen <= 0) {
+ errno = EMSGSIZE;
+ zed_log_msg(LOG_WARNING, "Failed to add %s for eid=%llu: %s",
+ keybuf, eid, "Exceeded buffer size");
+ return (-1);
+ }
+
va_start(vargs, fmt);
n = vsnprintf(dstp, buflen, fmt, vargs);
va_end(vargs);
name = nvpair_name(nvp);
(void) nvpair_value_int64_array(nvp, &i64p, &nelem);
for (i = 0, p = buf; (i < nelem) && (buflen > 0); i++) {
- n = snprintf(p, buflen, "%lld ", (u_longlong_t) i64p[i]);
+ n = snprintf(p, buflen, "%lld ", (u_longlong_t)i64p[i]);
if ((n < 0) || (n >= buflen))
return (_zed_event_add_array_err(eid, name));
p += n;
fmt = _zed_event_value_is_hex(name) ? "0x%.16llX " : "%llu ";
(void) nvpair_value_uint64_array(nvp, &u64p, &nelem);
for (i = 0, p = buf; (i < nelem) && (buflen > 0); i++) {
- n = snprintf(p, buflen, fmt, (u_longlong_t) u64p[i]);
+ n = snprintf(p, buflen, fmt, (u_longlong_t)u64p[i]);
if ((n < 0) || (n >= buflen))
return (_zed_event_add_array_err(eid, name));
p += n;
_zed_event_add_var(eid, zsp, prefix, name, "%d", i8);
break;
case DATA_TYPE_INT8:
- (void) nvpair_value_int8(nvp, (int8_t *) &i8);
+ (void) nvpair_value_int8(nvp, (int8_t *)&i8);
_zed_event_add_var(eid, zsp, prefix, name, "%d", i8);
break;
case DATA_TYPE_UINT8:
_zed_event_add_var(eid, zsp, prefix, name, "%u", i8);
break;
case DATA_TYPE_INT16:
- (void) nvpair_value_int16(nvp, (int16_t *) &i16);
+ (void) nvpair_value_int16(nvp, (int16_t *)&i16);
_zed_event_add_var(eid, zsp, prefix, name, "%d", i16);
break;
case DATA_TYPE_UINT16:
_zed_event_add_var(eid, zsp, prefix, name, "%u", i16);
break;
case DATA_TYPE_INT32:
- (void) nvpair_value_int32(nvp, (int32_t *) &i32);
+ (void) nvpair_value_int32(nvp, (int32_t *)&i32);
_zed_event_add_var(eid, zsp, prefix, name, "%d", i32);
break;
case DATA_TYPE_UINT32:
_zed_event_add_var(eid, zsp, prefix, name, "%u", i32);
break;
case DATA_TYPE_INT64:
- (void) nvpair_value_int64(nvp, (int64_t *) &i64);
+ (void) nvpair_value_int64(nvp, (int64_t *)&i64);
_zed_event_add_var(eid, zsp, prefix, name,
- "%lld", (longlong_t) i64);
+ "%lld", (longlong_t)i64);
break;
case DATA_TYPE_UINT64:
(void) nvpair_value_uint64(nvp, &i64);
_zed_event_add_var(eid, zsp, prefix, name,
(_zed_event_value_is_hex(name) ? "0x%.16llX" : "%llu"),
- (u_longlong_t) i64);
+ (u_longlong_t)i64);
+ /*
+ * shadow readable strings for vdev state pairs
+ */
+ if (strcmp(name, FM_EREPORT_PAYLOAD_ZFS_VDEV_STATE) == 0 ||
+ strcmp(name, FM_EREPORT_PAYLOAD_ZFS_VDEV_LASTSTATE) == 0) {
+ char alt[32];
+
+ (void) snprintf(alt, sizeof (alt), "%s_str", name);
+ _zed_event_add_var(eid, zsp, prefix, alt, "%s",
+ zpool_state_to_name(i64, VDEV_AUX_NONE));
+ } else
+ /*
+ * shadow readable strings for pool state
+ */
+ if (strcmp(name, FM_EREPORT_PAYLOAD_ZFS_POOL_STATE) == 0) {
+ char alt[32];
+
+ (void) snprintf(alt, sizeof (alt), "%s_str", name);
+ _zed_event_add_var(eid, zsp, prefix, alt, "%s",
+ zpool_pool_state_to_name(i64));
+ }
break;
case DATA_TYPE_DOUBLE:
(void) nvpair_value_double(nvp, &d);
_zed_event_add_var(eid, zsp, prefix, name, "%g", d);
break;
case DATA_TYPE_HRTIME:
- (void) nvpair_value_hrtime(nvp, (hrtime_t *) &i64);
+ (void) nvpair_value_hrtime(nvp, (hrtime_t *)&i64);
_zed_event_add_var(eid, zsp, prefix, name,
- "%llu", (u_longlong_t) i64);
+ "%llu", (u_longlong_t)i64);
break;
case DATA_TYPE_NVLIST:
_zed_event_add_var(eid, zsp, prefix, name,
/*
* Compute the "subclass" by removing the first 3 components of [class]
- * (which seem to always be either "ereport.fs.zfs" or "resource.fs.zfs").
- * Return a pointer inside the string [class], or NULL if insufficient
- * components exist.
+ * (which will always be of the form "*.fs.zfs"). Return a pointer inside
+ * the string [class], or NULL if insufficient components exist.
*/
static const char *
_zed_event_get_subclass(const char *class)
zed_log_msg(LOG_WARNING,
"Failed to lookup zevent class (eid=%llu)", eid);
} else {
+ /* let internal modules see this event first */
+ zfs_agent_post_event(class, NULL, nvl);
+
zsp = zed_strings_create();
nvp = NULL;
_zed_event_add_env_preserve(eid, zsp);
_zed_event_add_var(eid, zsp, ZED_VAR_PREFIX, "PID",
- "%d", (int) getpid());
+ "%d", (int)getpid());
_zed_event_add_var(eid, zsp, ZED_VAR_PREFIX, "ZEDLET_DIR",
"%s", zcp->zedlet_dir);
subclass = _zed_event_get_subclass(class);
_zed_event_add_var(eid, zsp, ZEVENT_VAR_PREFIX, "SUBCLASS",
"%s", (subclass ? subclass : class));
+
_zed_event_add_time_strings(eid, zsp, etime);
zed_exec_process(eid, class, subclass,