zed_log_die("Failed to open \"%s\": %s",
ZFS_DEV, strerror(errno));
- if (zfs_slm_init(zcp->zfs_hdl) != 0)
- zed_log_die("Failed to initialize zfs slm");
- if (zfs_diagnosis_init(zcp->zfs_hdl) != 0)
- zed_log_die("Failed to initialize zfs diagnosis");
- if (zfs_retire_init(zcp->zfs_hdl) != 0)
- zed_log_die("Failed to initialize zfs retire");
+ zfs_agent_init(zcp->zfs_hdl);
+
if (zed_disk_event_init() != 0)
zed_log_die("Failed to initialize disk events");
}
zed_log_die("Failed zed_event_fini: %s", strerror(EINVAL));
zed_disk_event_fini();
- zfs_retire_fini();
- zfs_diagnosis_fini();
- zfs_slm_fini();
+ zfs_agent_fini();
if (zcp->zevent_fd >= 0) {
if (close(zcp->zevent_fd) < 0)
*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
*/
(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:
_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,
/*
* Restrict various environment variables to safe and sane values
- * when constructing the environment for the child process.
+ * when constructing the environment for the child process, unless
+ * we're running with a custom $PATH (like under the ZFS test suite).
*
* Reference: Secure Programming Cookbook by Viega & Messier, Section 1.1.
*/
static void
-_zed_event_add_env_restrict(uint64_t eid, zed_strings_t *zsp)
+_zed_event_add_env_restrict(uint64_t eid, zed_strings_t *zsp,
+ const char *path)
{
const char *env_restrict[][2] = {
{ "IFS", " \t\n" },
{ "ZFS_RELEASE", ZFS_META_RELEASE },
{ NULL, NULL }
};
+
+ /*
+ * If we have a custom $PATH, use the default ZFS binary locations
+ * instead of the hard-coded ones.
+ */
+ const char *env_path[][2] = {
+ { "IFS", " \t\n" },
+ { "PATH", NULL }, /* $PATH copied in later on */
+ { "ZDB", "zdb" },
+ { "ZED", "zed" },
+ { "ZFS", "zfs" },
+ { "ZINJECT", "zinject" },
+ { "ZPOOL", "zpool" },
+ { "ZFS_ALIAS", ZFS_META_ALIAS },
+ { "ZFS_VERSION", ZFS_META_VERSION },
+ { "ZFS_RELEASE", ZFS_META_RELEASE },
+ { NULL, NULL }
+ };
const char *(*pa)[2];
assert(zsp != NULL);
- for (pa = env_restrict; *(*pa); pa++) {
+ pa = path != NULL ? env_path : env_restrict;
+
+ for (; *(*pa); pa++) {
+ /* Use our custom $PATH if we have one */
+ if (path != NULL && strcmp((*pa)[0], "PATH") == 0)
+ (*pa)[1] = path;
+
_zed_event_add_var(eid, zsp, NULL, (*pa)[0], "%s", (*pa)[1]);
}
}
}
}
-static void
-_zed_internal_event(const char *class, nvlist_t *nvl)
-{
- /*
- * NOTE: only vdev check is handled for now
- */
- if (strcmp(class, "sysevent.fs.zfs.vdev_check") == 0) {
- (void) zfs_slm_event("EC_zfs", "ESC_ZFS_vdev_check", nvl);
- }
-}
-
/*
* Service the next zevent, blocking until one is available.
*/
"Failed to lookup zevent class (eid=%llu)", eid);
} else {
/* let internal modules see this event first */
- _zed_internal_event(class, nvl);
+ zfs_agent_post_event(class, NULL, nvl);
zsp = zed_strings_create();
while ((nvp = nvlist_next_nvpair(nvl, nvp)))
_zed_event_add_nvpair(eid, zsp, nvp);
- _zed_event_add_env_restrict(eid, zsp);
+ _zed_event_add_env_restrict(eid, zsp, zcp->path);
_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,