diff options
-rw-r--r-- | cmd/zed/zed.c | 29 | ||||
-rw-r--r-- | cmd/zed/zed_conf.c | 7 | ||||
-rw-r--r-- | cmd/zed/zed_conf.h | 1 | ||||
-rw-r--r-- | cmd/zed/zed_event.c | 26 | ||||
-rw-r--r-- | cmd/zed/zed_event.h | 4 | ||||
-rw-r--r-- | man/man8/zed.8.in | 7 |
6 files changed, 62 insertions, 12 deletions
diff --git a/cmd/zed/zed.c b/cmd/zed/zed.c index bba8b8f64..0784e3834 100644 --- a/cmd/zed/zed.c +++ b/cmd/zed/zed.c @@ -263,18 +263,43 @@ main(int argc, char *argv[]) if (zed_conf_read_state(zcp, &saved_eid, saved_etime) < 0) exit(EXIT_FAILURE); - zed_event_init(zcp); +idle: + /* + * If -I is specified, attempt to open /dev/zfs repeatedly until + * successful. + */ + do { + if (!zed_event_init(zcp)) + break; + /* Wait for some time and try again. tunable? */ + sleep(30); + } while (!_got_exit && zcp->do_idle); + + if (_got_exit) + goto out; + zed_event_seek(zcp, saved_eid, saved_etime); while (!_got_exit) { + int rv; if (_got_hup) { _got_hup = 0; (void) zed_conf_scan_dir(zcp); } - zed_event_service(zcp); + rv = zed_event_service(zcp); + + /* ENODEV: When kernel module is unloaded (osx) */ + if (rv == ENODEV) + break; } + zed_log_msg(LOG_NOTICE, "Exiting"); zed_event_fini(zcp); + + if (zcp->do_idle && !_got_exit) + goto idle; + +out: zed_conf_destroy(zcp); zed_log_fini(); exit(EXIT_SUCCESS); diff --git a/cmd/zed/zed_conf.c b/cmd/zed/zed_conf.c index 86671369c..52370eb87 100644 --- a/cmd/zed/zed_conf.c +++ b/cmd/zed/zed_conf.c @@ -153,6 +153,8 @@ _zed_conf_display_help(const char *prog, int got_err) "Force daemon to run."); fprintf(fp, "%*c%*s %s\n", w1, 0x20, -w2, "-F", "Run daemon in the foreground."); + fprintf(fp, "%*c%*s %s\n", w1, 0x20, -w2, "-I", + "Idle daemon until kernel module is (re)loaded."); fprintf(fp, "%*c%*s %s\n", w1, 0x20, -w2, "-M", "Lock all pages in memory."); fprintf(fp, "%*c%*s %s\n", w1, 0x20, -w2, "-P", @@ -249,7 +251,7 @@ _zed_conf_parse_path(char **resultp, const char *path) void zed_conf_parse_opts(struct zed_conf *zcp, int argc, char **argv) { - const char * const opts = ":hLVc:d:p:P:s:vfFMZ"; + const char * const opts = ":hLVc:d:p:P:s:vfFMZI"; int opt; if (!zcp || !argv || !argv[0]) @@ -274,6 +276,9 @@ zed_conf_parse_opts(struct zed_conf *zcp, int argc, char **argv) case 'd': _zed_conf_parse_path(&zcp->zedlet_dir, optarg); break; + case 'I': + zcp->do_idle = 1; + break; case 'p': _zed_conf_parse_path(&zcp->pid_file, optarg); break; diff --git a/cmd/zed/zed_conf.h b/cmd/zed/zed_conf.h index 7d6b63b1d..424cb2c01 100644 --- a/cmd/zed/zed_conf.h +++ b/cmd/zed/zed_conf.h @@ -25,6 +25,7 @@ struct zed_conf { unsigned do_memlock:1; /* true if locking memory */ unsigned do_verbose:1; /* true if verbosity enabled */ unsigned do_zero:1; /* true if zeroing state */ + unsigned do_idle:1; /* true if idle enabled */ int syslog_facility; /* syslog facility value */ int min_events; /* RESERVED FOR FUTURE USE */ int max_events; /* RESERVED FOR FUTURE USE */ diff --git a/cmd/zed/zed_event.c b/cmd/zed/zed_event.c index 197c25386..1c5d00e29 100644 --- a/cmd/zed/zed_event.c +++ b/cmd/zed/zed_event.c @@ -41,25 +41,36 @@ /* * Open the libzfs interface. */ -void +int zed_event_init(struct zed_conf *zcp) { if (!zcp) zed_log_die("Failed zed_event_init: %s", strerror(EINVAL)); zcp->zfs_hdl = libzfs_init(); - if (!zcp->zfs_hdl) + if (!zcp->zfs_hdl) { + if (zcp->do_idle) + return (-1); zed_log_die("Failed to initialize libzfs"); + } zcp->zevent_fd = open(ZFS_DEV, O_RDWR); - if (zcp->zevent_fd < 0) + if (zcp->zevent_fd < 0) { + if (zcp->do_idle) + return (-1); zed_log_die("Failed to open \"%s\": %s", ZFS_DEV, strerror(errno)); + } zfs_agent_init(zcp->zfs_hdl); - if (zed_disk_event_init() != 0) + if (zed_disk_event_init() != 0) { + if (zcp->do_idle) + return (-1); zed_log_die("Failed to initialize disk events"); + } + + return (0); } /* @@ -873,7 +884,7 @@ _zed_event_add_time_strings(uint64_t eid, zed_strings_t *zsp, int64_t etime[]) /* * Service the next zevent, blocking until one is available. */ -void +int zed_event_service(struct zed_conf *zcp) { nvlist_t *nvl; @@ -891,13 +902,13 @@ zed_event_service(struct zed_conf *zcp) errno = EINVAL; zed_log_msg(LOG_ERR, "Failed to service zevent: %s", strerror(errno)); - return; + return (EINVAL); } rv = zpool_events_next(zcp->zfs_hdl, &nvl, &n_dropped, ZEVENT_NONE, zcp->zevent_fd); if ((rv != 0) || !nvl) - return; + return (errno); if (n_dropped > 0) { zed_log_msg(LOG_WARNING, "Missed %d events", n_dropped); @@ -950,4 +961,5 @@ zed_event_service(struct zed_conf *zcp) zed_strings_destroy(zsp); } nvlist_free(nvl); + return (0); } diff --git a/cmd/zed/zed_event.h b/cmd/zed/zed_event.h index 9f37b80fe..c1455c3a0 100644 --- a/cmd/zed/zed_event.h +++ b/cmd/zed/zed_event.h @@ -17,13 +17,13 @@ #include <stdint.h> -void zed_event_init(struct zed_conf *zcp); +int zed_event_init(struct zed_conf *zcp); void zed_event_fini(struct zed_conf *zcp); int zed_event_seek(struct zed_conf *zcp, uint64_t saved_eid, int64_t saved_etime[]); -void zed_event_service(struct zed_conf *zcp); +int zed_event_service(struct zed_conf *zcp); #endif /* !ZED_EVENT_H */ diff --git a/man/man8/zed.8.in b/man/man8/zed.8.in index 2db223a68..2ca393572 100644 --- a/man/man8/zed.8.in +++ b/man/man8/zed.8.in @@ -24,6 +24,7 @@ ZED \- ZFS Event Daemon [\fB\-f\fR] [\fB\-F\fR] [\fB\-h\fR] +[\fB\-I\fR] [\fB\-L\fR] [\fB\-M\fR] [\fB\-p\fR \fIpidfile\fR] @@ -66,6 +67,12 @@ Lock all current and future pages in the virtual memory address space. This may help the daemon remain responsive when the system is under heavy memory pressure. .TP +.BI \-I +Request that the daemon idle rather than exit when the kernel modules are +not loaded. Processing of events will start, or resume, when the kernel +modules are (re)loaded. Under Linux the kernel modules cannot be unloaded +while the daemon is running. +.TP .BI \-Z Zero the daemon's state, thereby allowing zevents still within the kernel to be reprocessed. |