2 * This file is part of the ZFS Event Daemon (ZED)
3 * for ZFS on Linux (ZoL) <http://zfsonlinux.org/>.
4 * Developed at Lawrence Livermore National Laboratory (LLNL-CODE-403049).
5 * Copyright (C) 2013-2014 Lawrence Livermore National Security, LLC.
6 * Refer to the ZoL git commit log for authoritative copyright attribution.
8 * The contents of this file are subject to the terms of the
9 * Common Development and Distribution License Version 1.0 (CDDL-1.0).
10 * You can obtain a copy of the license from the top-level file
11 * "OPENSOLARIS.LICENSE" or at <http://opensource.org/licenses/CDDL-1.0>.
12 * You may not use this file except in compliance with the license.
18 #include <libzfs.h> /* FIXME: Replace with libzfs_core. */
24 #include <sys/zfs_ioctl.h>
32 #include "zed_strings.h"
37 * Open the libzfs interface.
40 zed_event_init(struct zed_conf *zcp)
43 zed_log_die("Failed zed_event_init: %s", strerror(EINVAL));
45 zcp->zfs_hdl = libzfs_init();
47 zed_log_die("Failed to initialize libzfs");
49 zcp->zevent_fd = open(ZFS_DEV, O_RDWR);
50 if (zcp->zevent_fd < 0)
51 zed_log_die("Failed to open \"%s\": %s",
52 ZFS_DEV, strerror(errno));
56 * Close the libzfs interface.
59 zed_event_fini(struct zed_conf *zcp)
62 zed_log_die("Failed zed_event_fini: %s", strerror(EINVAL));
64 if (zcp->zevent_fd >= 0) {
65 if (close(zcp->zevent_fd) < 0)
66 zed_log_msg(LOG_WARNING, "Failed to close \"%s\": %s",
67 ZFS_DEV, strerror(errno));
72 libzfs_fini(zcp->zfs_hdl);
78 * Seek to the event specified by [saved_eid] and [saved_etime].
79 * This protects against processing a given event more than once.
80 * Return 0 upon a successful seek to the specified event, or -1 otherwise.
82 * A zevent is considered to be uniquely specified by its (eid,time) tuple.
83 * The unsigned 64b eid is set to 1 when the kernel module is loaded, and
84 * incremented by 1 for each new event. Since the state file can persist
85 * across a kernel module reload, the time must be checked to ensure a match.
88 zed_event_seek(struct zed_conf *zcp, uint64_t saved_eid, int64_t saved_etime[])
100 zed_log_msg(LOG_ERR, "Failed to seek zevent: %s",
106 while ((eid < saved_eid) && !found) {
107 rv = zpool_events_next(zcp->zfs_hdl, &nvl, &n_dropped,
108 ZEVENT_NONBLOCK, zcp->zevent_fd);
110 if ((rv != 0) || !nvl)
114 zed_log_msg(LOG_WARNING, "Missed %d events", n_dropped);
116 * FIXME: Increase max size of event nvlist in
117 * /sys/module/zfs/parameters/zfs_zevent_len_max ?
120 if (nvlist_lookup_uint64(nvl, "eid", &eid) != 0) {
121 zed_log_msg(LOG_WARNING, "Failed to lookup zevent eid");
122 } else if (nvlist_lookup_int64_array(nvl, "time",
123 &etime, &nelem) != 0) {
124 zed_log_msg(LOG_WARNING,
125 "Failed to lookup zevent time (eid=%llu)", eid);
126 } else if (nelem != 2) {
127 zed_log_msg(LOG_WARNING,
128 "Failed to lookup zevent time (eid=%llu, nelem=%u)",
130 } else if ((eid != saved_eid) ||
131 (etime[0] != saved_etime[0]) ||
132 (etime[1] != saved_etime[1])) {
139 if (!found && (saved_eid > 0)) {
140 if (zpool_events_seek(zcp->zfs_hdl, ZEVENT_SEEK_START,
142 zed_log_msg(LOG_WARNING, "Failed to seek to eid=0");
146 zed_log_msg(LOG_NOTICE, "Processing events since eid=%llu", eid);
147 return (found ? 0 : -1);
151 * Return non-zero if nvpair [name] should be formatted in hex; o/w, return 0.
154 _zed_event_value_is_hex(const char *name)
156 const char *hex_suffix[] = {
167 for (pp = hex_suffix; *pp; pp++) {
168 p = strstr(name, *pp);
169 if (p && strlen(p) == strlen(*pp))
176 * Add an environment variable for [eid] to the container [zsp].
178 * The variable name is the concatenation of [prefix] and [name] converted to
179 * uppercase with non-alphanumeric characters converted to underscores;
180 * [prefix] is optional, and [name] must begin with an alphabetic character.
181 * If the converted variable name already exists within the container [zsp],
182 * its existing value will be replaced with the new value.
184 * The variable value is specified by the format string [fmt].
186 * Returns 0 on success, and -1 on error (with errno set).
188 * All environment variables in [zsp] should be added through this function.
191 _zed_event_add_var(uint64_t eid, zed_strings_t *zsp,
192 const char *prefix, const char *name, const char *fmt, ...)
208 zed_log_msg(LOG_WARNING,
209 "Failed to add variable for eid=%llu: Name is empty", eid);
211 } else if (!isalpha(name[0])) {
213 zed_log_msg(LOG_WARNING,
214 "Failed to add variable for eid=%llu: "
215 "Name \"%s\" is invalid", eid, name);
219 * Construct the string key by converting PREFIX (if present) and NAME.
222 lastp = keybuf + sizeof (keybuf);
224 for (srcp = prefix; *srcp && (dstp < lastp); srcp++)
225 *dstp++ = isalnum(*srcp) ? toupper(*srcp) : '_';
227 for (srcp = name; *srcp && (dstp < lastp); srcp++)
228 *dstp++ = isalnum(*srcp) ? toupper(*srcp) : '_';
231 errno = ENAMETOOLONG;
232 zed_log_msg(LOG_WARNING,
233 "Failed to add variable for eid=%llu: Name too long", eid);
238 * Construct the string specified by "[PREFIX][NAME]=[FMT]".
241 buflen = sizeof (valbuf);
242 n = strlcpy(dstp, keybuf, buflen);
243 if (n >= sizeof (valbuf)) {
245 zed_log_msg(LOG_WARNING, "Failed to add %s for eid=%llu: %s",
246 keybuf, eid, "Exceeded buffer size");
255 va_start(vargs, fmt);
256 n = vsnprintf(dstp, buflen, fmt, vargs);
259 if ((n < 0) || (n >= buflen)) {
261 zed_log_msg(LOG_WARNING, "Failed to add %s for eid=%llu: %s",
262 keybuf, eid, "Exceeded buffer size");
264 } else if (zed_strings_add(zsp, keybuf, valbuf) < 0) {
265 zed_log_msg(LOG_WARNING, "Failed to add %s for eid=%llu: %s",
266 keybuf, eid, strerror(errno));
273 _zed_event_add_array_err(uint64_t eid, const char *name)
276 zed_log_msg(LOG_WARNING,
277 "Failed to convert nvpair \"%s\" for eid=%llu: "
278 "Exceeded buffer size", name, eid);
283 _zed_event_add_int8_array(uint64_t eid, zed_strings_t *zsp,
284 const char *prefix, nvpair_t *nvp)
287 int buflen = sizeof (buf);
295 assert((nvp != NULL) && (nvpair_type(nvp) == DATA_TYPE_INT8_ARRAY));
297 name = nvpair_name(nvp);
298 (void) nvpair_value_int8_array(nvp, &i8p, &nelem);
299 for (i = 0, p = buf; (i < nelem) && (buflen > 0); i++) {
300 n = snprintf(p, buflen, "%d ", i8p[i]);
301 if ((n < 0) || (n >= buflen))
302 return (_zed_event_add_array_err(eid, name));
309 return (_zed_event_add_var(eid, zsp, prefix, name, "%s", buf));
313 _zed_event_add_uint8_array(uint64_t eid, zed_strings_t *zsp,
314 const char *prefix, nvpair_t *nvp)
317 int buflen = sizeof (buf);
325 assert((nvp != NULL) && (nvpair_type(nvp) == DATA_TYPE_UINT8_ARRAY));
327 name = nvpair_name(nvp);
328 (void) nvpair_value_uint8_array(nvp, &u8p, &nelem);
329 for (i = 0, p = buf; (i < nelem) && (buflen > 0); i++) {
330 n = snprintf(p, buflen, "%u ", u8p[i]);
331 if ((n < 0) || (n >= buflen))
332 return (_zed_event_add_array_err(eid, name));
339 return (_zed_event_add_var(eid, zsp, prefix, name, "%s", buf));
343 _zed_event_add_int16_array(uint64_t eid, zed_strings_t *zsp,
344 const char *prefix, nvpair_t *nvp)
347 int buflen = sizeof (buf);
355 assert((nvp != NULL) && (nvpair_type(nvp) == DATA_TYPE_INT16_ARRAY));
357 name = nvpair_name(nvp);
358 (void) nvpair_value_int16_array(nvp, &i16p, &nelem);
359 for (i = 0, p = buf; (i < nelem) && (buflen > 0); i++) {
360 n = snprintf(p, buflen, "%d ", i16p[i]);
361 if ((n < 0) || (n >= buflen))
362 return (_zed_event_add_array_err(eid, name));
369 return (_zed_event_add_var(eid, zsp, prefix, name, "%s", buf));
373 _zed_event_add_uint16_array(uint64_t eid, zed_strings_t *zsp,
374 const char *prefix, nvpair_t *nvp)
377 int buflen = sizeof (buf);
385 assert((nvp != NULL) && (nvpair_type(nvp) == DATA_TYPE_UINT16_ARRAY));
387 name = nvpair_name(nvp);
388 (void) nvpair_value_uint16_array(nvp, &u16p, &nelem);
389 for (i = 0, p = buf; (i < nelem) && (buflen > 0); i++) {
390 n = snprintf(p, buflen, "%u ", u16p[i]);
391 if ((n < 0) || (n >= buflen))
392 return (_zed_event_add_array_err(eid, name));
399 return (_zed_event_add_var(eid, zsp, prefix, name, "%s", buf));
403 _zed_event_add_int32_array(uint64_t eid, zed_strings_t *zsp,
404 const char *prefix, nvpair_t *nvp)
407 int buflen = sizeof (buf);
415 assert((nvp != NULL) && (nvpair_type(nvp) == DATA_TYPE_INT32_ARRAY));
417 name = nvpair_name(nvp);
418 (void) nvpair_value_int32_array(nvp, &i32p, &nelem);
419 for (i = 0, p = buf; (i < nelem) && (buflen > 0); i++) {
420 n = snprintf(p, buflen, "%d ", i32p[i]);
421 if ((n < 0) || (n >= buflen))
422 return (_zed_event_add_array_err(eid, name));
429 return (_zed_event_add_var(eid, zsp, prefix, name, "%s", buf));
433 _zed_event_add_uint32_array(uint64_t eid, zed_strings_t *zsp,
434 const char *prefix, nvpair_t *nvp)
437 int buflen = sizeof (buf);
445 assert((nvp != NULL) && (nvpair_type(nvp) == DATA_TYPE_UINT32_ARRAY));
447 name = nvpair_name(nvp);
448 (void) nvpair_value_uint32_array(nvp, &u32p, &nelem);
449 for (i = 0, p = buf; (i < nelem) && (buflen > 0); i++) {
450 n = snprintf(p, buflen, "%u ", u32p[i]);
451 if ((n < 0) || (n >= buflen))
452 return (_zed_event_add_array_err(eid, name));
459 return (_zed_event_add_var(eid, zsp, prefix, name, "%s", buf));
463 _zed_event_add_int64_array(uint64_t eid, zed_strings_t *zsp,
464 const char *prefix, nvpair_t *nvp)
467 int buflen = sizeof (buf);
475 assert((nvp != NULL) && (nvpair_type(nvp) == DATA_TYPE_INT64_ARRAY));
477 name = nvpair_name(nvp);
478 (void) nvpair_value_int64_array(nvp, &i64p, &nelem);
479 for (i = 0, p = buf; (i < nelem) && (buflen > 0); i++) {
480 n = snprintf(p, buflen, "%lld ", (u_longlong_t) i64p[i]);
481 if ((n < 0) || (n >= buflen))
482 return (_zed_event_add_array_err(eid, name));
489 return (_zed_event_add_var(eid, zsp, prefix, name, "%s", buf));
493 _zed_event_add_uint64_array(uint64_t eid, zed_strings_t *zsp,
494 const char *prefix, nvpair_t *nvp)
497 int buflen = sizeof (buf);
506 assert((nvp != NULL) && (nvpair_type(nvp) == DATA_TYPE_UINT64_ARRAY));
508 name = nvpair_name(nvp);
509 fmt = _zed_event_value_is_hex(name) ? "0x%.16llX " : "%llu ";
510 (void) nvpair_value_uint64_array(nvp, &u64p, &nelem);
511 for (i = 0, p = buf; (i < nelem) && (buflen > 0); i++) {
512 n = snprintf(p, buflen, fmt, (u_longlong_t) u64p[i]);
513 if ((n < 0) || (n >= buflen))
514 return (_zed_event_add_array_err(eid, name));
521 return (_zed_event_add_var(eid, zsp, prefix, name, "%s", buf));
525 _zed_event_add_string_array(uint64_t eid, zed_strings_t *zsp,
526 const char *prefix, nvpair_t *nvp)
529 int buflen = sizeof (buf);
537 assert((nvp != NULL) && (nvpair_type(nvp) == DATA_TYPE_STRING_ARRAY));
539 name = nvpair_name(nvp);
540 (void) nvpair_value_string_array(nvp, &strp, &nelem);
541 for (i = 0, p = buf; (i < nelem) && (buflen > 0); i++) {
542 n = snprintf(p, buflen, "%s ", strp[i] ? strp[i] : "<NULL>");
543 if ((n < 0) || (n >= buflen))
544 return (_zed_event_add_array_err(eid, name));
551 return (_zed_event_add_var(eid, zsp, prefix, name, "%s", buf));
555 * Convert the nvpair [nvp] to a string which is added to the environment
556 * of the child process.
557 * Return 0 on success, -1 on error.
559 * FIXME: Refactor with cmd/zpool/zpool_main.c:zpool_do_events_nvprint()?
562 _zed_event_add_nvpair(uint64_t eid, zed_strings_t *zsp, nvpair_t *nvp)
566 const char *prefix = ZEVENT_VAR_PREFIX;
578 name = nvpair_name(nvp);
579 type = nvpair_type(nvp);
582 case DATA_TYPE_BOOLEAN:
583 _zed_event_add_var(eid, zsp, prefix, name, "%s", "1");
585 case DATA_TYPE_BOOLEAN_VALUE:
586 (void) nvpair_value_boolean_value(nvp, &b);
587 _zed_event_add_var(eid, zsp, prefix, name, "%s", b ? "1" : "0");
590 (void) nvpair_value_byte(nvp, &i8);
591 _zed_event_add_var(eid, zsp, prefix, name, "%d", i8);
594 (void) nvpair_value_int8(nvp, (int8_t *) &i8);
595 _zed_event_add_var(eid, zsp, prefix, name, "%d", i8);
597 case DATA_TYPE_UINT8:
598 (void) nvpair_value_uint8(nvp, &i8);
599 _zed_event_add_var(eid, zsp, prefix, name, "%u", i8);
601 case DATA_TYPE_INT16:
602 (void) nvpair_value_int16(nvp, (int16_t *) &i16);
603 _zed_event_add_var(eid, zsp, prefix, name, "%d", i16);
605 case DATA_TYPE_UINT16:
606 (void) nvpair_value_uint16(nvp, &i16);
607 _zed_event_add_var(eid, zsp, prefix, name, "%u", i16);
609 case DATA_TYPE_INT32:
610 (void) nvpair_value_int32(nvp, (int32_t *) &i32);
611 _zed_event_add_var(eid, zsp, prefix, name, "%d", i32);
613 case DATA_TYPE_UINT32:
614 (void) nvpair_value_uint32(nvp, &i32);
615 _zed_event_add_var(eid, zsp, prefix, name, "%u", i32);
617 case DATA_TYPE_INT64:
618 (void) nvpair_value_int64(nvp, (int64_t *) &i64);
619 _zed_event_add_var(eid, zsp, prefix, name,
620 "%lld", (longlong_t) i64);
622 case DATA_TYPE_UINT64:
623 (void) nvpair_value_uint64(nvp, &i64);
624 _zed_event_add_var(eid, zsp, prefix, name,
625 (_zed_event_value_is_hex(name) ? "0x%.16llX" : "%llu"),
628 case DATA_TYPE_DOUBLE:
629 (void) nvpair_value_double(nvp, &d);
630 _zed_event_add_var(eid, zsp, prefix, name, "%g", d);
632 case DATA_TYPE_HRTIME:
633 (void) nvpair_value_hrtime(nvp, (hrtime_t *) &i64);
634 _zed_event_add_var(eid, zsp, prefix, name,
635 "%llu", (u_longlong_t) i64);
637 case DATA_TYPE_NVLIST:
638 _zed_event_add_var(eid, zsp, prefix, name,
639 "%s", "_NOT_IMPLEMENTED_"); /* FIXME */
641 case DATA_TYPE_STRING:
642 (void) nvpair_value_string(nvp, &str);
643 _zed_event_add_var(eid, zsp, prefix, name,
644 "%s", (str ? str : "<NULL>"));
646 case DATA_TYPE_BOOLEAN_ARRAY:
647 _zed_event_add_var(eid, zsp, prefix, name,
648 "%s", "_NOT_IMPLEMENTED_"); /* FIXME */
650 case DATA_TYPE_BYTE_ARRAY:
651 _zed_event_add_var(eid, zsp, prefix, name,
652 "%s", "_NOT_IMPLEMENTED_"); /* FIXME */
654 case DATA_TYPE_INT8_ARRAY:
655 _zed_event_add_int8_array(eid, zsp, prefix, nvp);
657 case DATA_TYPE_UINT8_ARRAY:
658 _zed_event_add_uint8_array(eid, zsp, prefix, nvp);
660 case DATA_TYPE_INT16_ARRAY:
661 _zed_event_add_int16_array(eid, zsp, prefix, nvp);
663 case DATA_TYPE_UINT16_ARRAY:
664 _zed_event_add_uint16_array(eid, zsp, prefix, nvp);
666 case DATA_TYPE_INT32_ARRAY:
667 _zed_event_add_int32_array(eid, zsp, prefix, nvp);
669 case DATA_TYPE_UINT32_ARRAY:
670 _zed_event_add_uint32_array(eid, zsp, prefix, nvp);
672 case DATA_TYPE_INT64_ARRAY:
673 _zed_event_add_int64_array(eid, zsp, prefix, nvp);
675 case DATA_TYPE_UINT64_ARRAY:
676 _zed_event_add_uint64_array(eid, zsp, prefix, nvp);
678 case DATA_TYPE_STRING_ARRAY:
679 _zed_event_add_string_array(eid, zsp, prefix, nvp);
681 case DATA_TYPE_NVLIST_ARRAY:
682 _zed_event_add_var(eid, zsp, prefix, name,
683 "%s", "_NOT_IMPLEMENTED_"); /* FIXME */
687 zed_log_msg(LOG_WARNING,
688 "Failed to convert nvpair \"%s\" for eid=%llu: "
689 "Unrecognized type=%u", name, eid, (unsigned int) type);
695 * Restrict various environment variables to safe and sane values
696 * when constructing the environment for the child process.
698 * Reference: Secure Programming Cookbook by Viega & Messier, Section 1.1.
701 _zed_event_add_env_restrict(uint64_t eid, zed_strings_t *zsp)
703 const char *env_restrict[][2] = {
705 { "PATH", _PATH_STDPATH },
706 { "ZDB", SBINDIR "/zdb" },
707 { "ZED", SBINDIR "/zed" },
708 { "ZFS", SBINDIR "/zfs" },
709 { "ZINJECT", SBINDIR "/zinject" },
710 { "ZPOOL", SBINDIR "/zpool" },
711 { "ZFS_ALIAS", ZFS_META_ALIAS },
712 { "ZFS_VERSION", ZFS_META_VERSION },
713 { "ZFS_RELEASE", ZFS_META_RELEASE },
716 const char *(*pa)[2];
720 for (pa = env_restrict; *(*pa); pa++) {
721 _zed_event_add_var(eid, zsp, NULL, (*pa)[0], "%s", (*pa)[1]);
726 * Preserve specified variables from the parent environment
727 * when constructing the environment for the child process.
729 * Reference: Secure Programming Cookbook by Viega & Messier, Section 1.1.
732 _zed_event_add_env_preserve(uint64_t eid, zed_strings_t *zsp)
734 const char *env_preserve[] = {
743 for (keyp = env_preserve; *keyp; keyp++) {
744 if ((val = getenv(*keyp)))
745 _zed_event_add_var(eid, zsp, NULL, *keyp, "%s", val);
750 * Compute the "subclass" by removing the first 3 components of [class]
751 * (which will always be of the form "*.fs.zfs"). Return a pointer inside
752 * the string [class], or NULL if insufficient components exist.
755 _zed_event_get_subclass(const char *class)
764 for (i = 0; i < 3; i++) {
774 * Convert the zevent time from a 2-element array of 64b integers
775 * into a more convenient form:
776 * - TIME_SECS is the second component of the time.
777 * - TIME_NSECS is the nanosecond component of the time.
778 * - TIME_STRING is an almost-RFC3339-compliant string representation.
781 _zed_event_add_time_strings(uint64_t eid, zed_strings_t *zsp, int64_t etime[])
787 assert(etime != NULL);
789 _zed_event_add_var(eid, zsp, ZEVENT_VAR_PREFIX, "TIME_SECS",
790 "%lld", (long long int) etime[0]);
791 _zed_event_add_var(eid, zsp, ZEVENT_VAR_PREFIX, "TIME_NSECS",
792 "%lld", (long long int) etime[1]);
794 if (!(stp = localtime((const time_t *) &etime[0]))) {
795 zed_log_msg(LOG_WARNING, "Failed to add %s%s for eid=%llu: %s",
796 ZEVENT_VAR_PREFIX, "TIME_STRING", eid, "localtime error");
797 } else if (!strftime(buf, sizeof (buf), "%Y-%m-%d %H:%M:%S%z", stp)) {
798 zed_log_msg(LOG_WARNING, "Failed to add %s%s for eid=%llu: %s",
799 ZEVENT_VAR_PREFIX, "TIME_STRING", eid, "strftime error");
801 _zed_event_add_var(eid, zsp, ZEVENT_VAR_PREFIX, "TIME_STRING",
807 * Service the next zevent, blocking until one is available.
810 zed_event_service(struct zed_conf *zcp)
820 const char *subclass;
825 zed_log_msg(LOG_ERR, "Failed to service zevent: %s",
829 rv = zpool_events_next(zcp->zfs_hdl, &nvl, &n_dropped, ZEVENT_NONE,
832 if ((rv != 0) || !nvl)
836 zed_log_msg(LOG_WARNING, "Missed %d events", n_dropped);
838 * FIXME: Increase max size of event nvlist in
839 * /sys/module/zfs/parameters/zfs_zevent_len_max ?
842 if (nvlist_lookup_uint64(nvl, "eid", &eid) != 0) {
843 zed_log_msg(LOG_WARNING, "Failed to lookup zevent eid");
844 } else if (nvlist_lookup_int64_array(
845 nvl, "time", &etime, &nelem) != 0) {
846 zed_log_msg(LOG_WARNING,
847 "Failed to lookup zevent time (eid=%llu)", eid);
848 } else if (nelem != 2) {
849 zed_log_msg(LOG_WARNING,
850 "Failed to lookup zevent time (eid=%llu, nelem=%u)",
852 } else if (nvlist_lookup_string(nvl, "class", &class) != 0) {
853 zed_log_msg(LOG_WARNING,
854 "Failed to lookup zevent class (eid=%llu)", eid);
856 zsp = zed_strings_create();
859 while ((nvp = nvlist_next_nvpair(nvl, nvp)))
860 _zed_event_add_nvpair(eid, zsp, nvp);
862 _zed_event_add_env_restrict(eid, zsp);
863 _zed_event_add_env_preserve(eid, zsp);
865 _zed_event_add_var(eid, zsp, ZED_VAR_PREFIX, "PID",
866 "%d", (int) getpid());
867 _zed_event_add_var(eid, zsp, ZED_VAR_PREFIX, "ZEDLET_DIR",
868 "%s", zcp->zedlet_dir);
869 subclass = _zed_event_get_subclass(class);
870 _zed_event_add_var(eid, zsp, ZEVENT_VAR_PREFIX, "SUBCLASS",
871 "%s", (subclass ? subclass : class));
872 _zed_event_add_time_strings(eid, zsp, etime);
874 zed_exec_process(eid, class, subclass,
875 zcp->zedlet_dir, zcp->zedlets, zsp, zcp->zevent_fd);
877 zed_conf_write_state(zcp, eid, etime);
879 zed_strings_destroy(zsp);