/*
* Lock all current and future pages in the virtual memory address space.
- * Access to locked pages will never be delayed by a page fault.
+ * Access to locked pages will never be delayed by a page fault.
+ *
* EAGAIN is tested up to max_tries in case this is a transient error.
+ *
* Note that memory locks are not inherited by a child created via fork()
- * and are automatically removed during an execve(). As such, this must
- * be called after the daemon fork()s (when running in the background).
+ * and are automatically removed during an execve(). As such, this must
+ * be called after the daemon fork()s (when running in the background).
*/
static void
_lock_memory(void)
/*
* Start daemonization of the process including the double fork().
+ *
* The parent process will block here until _finish_daemonize() is called
- * (in the grandchild process), at which point the parent process will exit.
- * This prevents the parent process from exiting until initialization is
- * complete.
+ * (in the grandchild process), at which point the parent process will exit.
+ * This prevents the parent process from exiting until initialization is
+ * complete.
*/
static void
_start_daemonize(void)
/*
* Finish daemonization of the process by closing stdin/stdout/stderr.
+ *
* This must be called at the end of initialization after all external
- * communication channels are established and accessible.
+ * communication channels are established and accessible.
*/
static void
_finish_daemonize(void)
/*
* Destroy the configuration [zcp].
+ *
* Note: zfs_hdl & zevent_fd are destroyed via zed_event_fini().
*/
void
/*
* Display command-line help and exit.
+ *
* If [got_err] is 0, output to stdout and exit normally;
- * otherwise, output to stderr and exit with a failure status.
+ * otherwise, output to stderr and exit with a failure status.
*/
static void
_zed_conf_display_help(const char *prog, int got_err)
/*
* Parse the configuration file into the configuration [zcp].
+ *
* FIXME: Not yet implemented.
*/
void
/*
* Scan the [zcp] script_dir for files to exec based on the event class.
- * Files must be executable by user, but not writable by group or other.
- * Dotfiles are ignored.
+ * Files must be executable by user, but not writable by group or other.
+ * Dotfiles are ignored.
+ *
* Return 0 on success with an updated set of scripts,
- * or -1 on error with errno set.
+ * or -1 on error with errno set.
+ *
* FIXME: Check if script_dir and all parent dirs are secure.
*/
int
/*
* Write the PID file specified in [zcp].
* Return 0 on success, -1 on error.
+ *
* This must be called after fork()ing to become a daemon (so the correct PID
- * is recorded), but before daemonization is complete and the parent process
- * exits (for synchronization with systemd).
+ * is recorded), but before daemonization is complete and the parent process
+ * exits (for synchronization with systemd).
+ *
* FIXME: Only update the PID file after verifying the PID previously stored
- * in the PID file no longer exists or belongs to a foreign process
- * in order to ensure the daemon cannot be started more than once.
- * (This check is currently done by zed_conf_open_state().)
+ * in the PID file no longer exists or belongs to a foreign process
+ * in order to ensure the daemon cannot be started more than once.
+ * (This check is currently done by zed_conf_open_state().)
*/
int
zed_conf_write_pid(struct zed_conf *zcp)
/*
* Open and lock the [zcp] state_file.
* Return 0 on success, -1 on error.
+ *
* FIXME: If state_file exists, verify ownership & permissions.
* FIXME: Move lock to pid_file instead.
*/
}
/*
- * Read the opened [zcp] state_file to obtain the eid & etime
- * of the last event processed.
- * Write the state from the last event to the [eidp] & [etime] args
- * passed by reference.
- * Note that etime[] is an array of size 2.
+ * Read the opened [zcp] state_file to obtain the eid & etime of the last event
+ * processed. Write the state from the last event to the [eidp] & [etime] args
+ * passed by reference. Note that etime[] is an array of size 2.
* Return 0 on success, -1 on error.
*/
int
/*
* Write the [eid] & [etime] of the last processed event to the opened
- * [zcp] state_file.
- * Note that etime[] is an array of size 2.
+ * [zcp] state_file. Note that etime[] is an array of size 2.
* Return 0 on success, -1 on error.
*/
int
/*
* Seek to the event specified by [saved_eid] and [saved_etime].
- * This protects against processing a given event more than once.
+ * This protects against processing a given event more than once.
* Return 0 upon a successful seek to the specified event, or -1 otherwise.
+ *
* A zevent is considered to be uniquely specified by its (eid,time) tuple.
- * The unsigned 64b eid is set to 1 when the kernel module is loaded, and
- * incremented by 1 for each new event. Since the state file can persist
- * across a kernel module reload, the time must be checked to ensure a match.
+ * The unsigned 64b eid is set to 1 when the kernel module is loaded, and
+ * incremented by 1 for each new event. Since the state file can persist
+ * across a kernel module reload, the time must be checked to ensure a match.
*/
int
zed_event_seek(struct zed_conf *zcp, uint64_t saved_eid, int64_t saved_etime[])
/*
* Convert the nvpair [nvp] to a string which is added to the environment
- * of the child process.
+ * of the child process.
* Return 0 on success, -1 on error.
+ *
* FIXME: Refactor with cmd/zpool/zpool_main.c:zpool_do_events_nvprint()?
*/
static void
/*
* 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.
+ *
* Reference: Secure Programming Cookbook by Viega & Messier, Section 1.1.
*/
static void
/*
* Preserve specified variables from the parent environment
- * when constructing the environment for the child process.
+ * when constructing the environment for the child process.
+ *
* Reference: Secure Programming Cookbook by Viega & Messier, Section 1.1.
*/
static void
/*
* Compute the "subclass" by removing the first 3 components of [class]
- * (which seem to always be either "ereport.fs.zfs" or "resource.fs.zfs").
+ * (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.
+ * components exist.
*/
static const char *
_zed_event_get_subclass(const char *class)
/*
* Convert the zevent time from a 2-element array of 64b integers
- * into a more convenient form:
- * TIME_SECS is the second component of the time.
- * TIME_NSECS is the nanosecond component of the time.
- * TIME_STRING is an almost-RFC3339-compliant string representation.
+ * into a more convenient form:
+ * - TIME_SECS is the second component of the time.
+ * - TIME_NSECS is the nanosecond component of the time.
+ * - TIME_STRING is an almost-RFC3339-compliant string representation.
*/
static void
_zed_event_add_time_strings(uint64_t eid, zed_strings_t *zsp, int64_t etime[])
zed_log_msg(LOG_WARNING, "Missed %d events", n_dropped);
/*
* FIXME: Increase max size of event nvlist in
- * /sys/module/zfs/parameters/zfs_zevent_len_max ?
+ * /sys/module/zfs/parameters/zfs_zevent_len_max ?
*/
}
if (nvlist_lookup_uint64(nvl, "eid", &eid) != 0) {
/*
* Create an environment string array for passing to execve() using the
- * NAME=VALUE strings in container [zsp].
+ * NAME=VALUE strings in container [zsp].
* Return a newly-allocated environment, or NULL on error.
*/
static char **
/*
* Fork a child process to handle event [eid]. The program [prog]
- * in directory [dir] is executed with the envionment [env].
+ * in directory [dir] is executed with the envionment [env].
+ *
* The file descriptor [zfd] is the zevent_fd used to track the
- * current cursor location within the zevent nvlist.
+ * current cursor location within the zevent nvlist.
*/
static void
_zed_exec_fork_child(uint64_t eid, const char *dir, const char *prog,
/*
* Process the event [eid] by synchronously invoking all scripts with a
- * matching class prefix.
+ * matching class prefix.
+ *
* Each executable in [scripts] from the directory [dir] is matched against
- * the event's [class], [subclass], and the "all" class (which matches
- * all events). Every script with a matching class prefix is invoked.
- * The NAME=VALUE strings in [envs] will be passed to the script as
- * environment variables.
+ * the event's [class], [subclass], and the "all" class (which matches
+ * all events). Every script with a matching class prefix is invoked.
+ * The NAME=VALUE strings in [envs] will be passed to the script as
+ * environment variables.
+ *
* The file descriptor [zfd] is the zevent_fd used to track the
- * current cursor location within the zevent nvlist.
+ * current cursor location within the zevent nvlist.
+ *
* Return 0 on success, -1 on error.
*/
int
/*
* Set an exclusive advisory lock on the open file descriptor [fd].
* Return 0 on success, 1 if a conflicting lock is held by another process,
- * or -1 on error (with errno set).
+ * or -1 on error (with errno set).
*/
int
zed_file_lock(int fd)
/*
* Test whether an exclusive advisory lock could be obtained for the open
- * file descriptor [fd].
+ * file descriptor [fd].
* Return 0 if the file is not locked, >0 for the PID of another process
- * holding a conflicting lock, or -1 on error (with errno set).
+ * holding a conflicting lock, or -1 on error (with errno set).
*/
pid_t
zed_file_is_locked(int fd)
/*
* Set the CLOEXEC flag on file descriptor [fd] so it will be automatically
- * closed upon successful execution of one of the exec functions.
+ * closed upon successful execution of one of the exec functions.
* Return 0 on success, or -1 on error.
+ *
* FIXME: No longer needed?
*/
int
/*
* Create pipe for communicating daemonization status between the parent and
- * child processes across the double-fork().
+ * child processes across the double-fork().
*/
void
zed_log_pipe_open(void)
/*
* Close the read-half of the daemonize pipe.
+ *
* This should be called by the child after fork()ing from the parent since
- * the child will never read from this pipe.
+ * the child will never read from this pipe.
*/
void
zed_log_pipe_close_reads(void)
/*
* Close the write-half of the daemonize pipe.
+ *
* This should be called by the parent after fork()ing its child since the
- * parent will never write to this pipe.
+ * parent will never write to this pipe.
+ *
* This should also be called by the child once initialization is complete
- * in order to signal the parent that it can safely exit.
+ * in order to signal the parent that it can safely exit.
*/
void
zed_log_pipe_close_writes(void)
/*
* Block on reading from the daemonize pipe until signaled by the child
- * (via zed_log_pipe_close_writes()) that initialization is complete.
+ * (via zed_log_pipe_close_writes()) that initialization is complete.
+ *
* This should only be called by the parent while waiting to exit after
- * fork()ing the child.
+ * fork()ing the child.
*/
void
zed_log_pipe_wait(void)
/*
* Start logging messages at the syslog [priority] level or higher to stderr.
- * Refer to syslog(3) for valid priority values.
+ * Refer to syslog(3) for valid priority values.
*/
void
zed_log_stderr_open(int priority)
/*
* Start logging messages to syslog.
- * Refer to syslog(3) for valid option/facility values.
+ * Refer to syslog(3) for valid option/facility values.
*/
void
zed_log_syslog_open(int facility)
/*
* Log a message at the given [priority] level specified by the printf-style
- * format string [fmt].
+ * format string [fmt].
*/
void
zed_log_msg(int priority, const char *fmt, ...)
/*
* Compare zed_strings_node_t nodes [x1] and [x2].
- * As required for the AVL tree, return exactly
- * -1 for <, 0 for ==, and +1 for >.
+ * As required for the AVL tree, return -1 for <, 0 for ==, and +1 for >.
*/
static int
_zed_strings_node_compare(const void *x1, const void *x2)
/*
* Add a copy of the string [s] to the container [zsp].
* Return 0 on success, or -1 on error.
+ *
* FIXME: Handle dup strings.
*/
int