Add .zfs control directory
[zfs.git] / module / zfs / fm.c
index 67d0c1a..e4ecfea 100644 (file)
@@ -76,9 +76,9 @@
 #include <sys/time.h>
 #include <sys/zfs_ioctl.h>
 
-int zevent_len_max = 0;
-int zevent_cols = 80;
-int zevent_console = 0;
+int zfs_zevent_len_max = 0;
+int zfs_zevent_cols = 80;
+int zfs_zevent_console = 0;
 
 static int zevent_len_cur = 0;
 static int zevent_waiters = 0;
@@ -405,9 +405,9 @@ fm_nvprint(nvlist_t *nvl)
        console_printf("\n");
 
        if (nvlist_lookup_string(nvl, FM_CLASS, &class) == 0)
-               c = fm_printf(0, c, zevent_cols, "%s", class);
+               c = fm_printf(0, c, zfs_zevent_cols, "%s", class);
 
-       if (fm_nvprintr(nvl, 0, c, zevent_cols) != 0)
+       if (fm_nvprintr(nvl, 0, c, zfs_zevent_cols) != 0)
                console_printf("\n");
 
        console_printf("\n");
@@ -483,7 +483,7 @@ zfs_zevent_insert(zevent_t *ev)
 {
        mutex_enter(&zevent_lock);
        list_insert_head(&zevent_list, ev);
-       if (zevent_len_cur >= zevent_len_max)
+       if (zevent_len_cur >= zfs_zevent_len_max)
                zfs_zevent_drain(list_tail(&zevent_list));
        else
                zevent_len_cur++;
@@ -516,7 +516,7 @@ zfs_zevent_post(nvlist_t *nvl, nvlist_t *detector, zevent_cb_t *cb)
                return;
        }
 
-       if (zevent_console)
+       if (zfs_zevent_console)
                fm_nvprint(nvl);
 
        ev = zfs_zevent_alloc();
@@ -568,13 +568,18 @@ zfs_zevent_fd_rele(int fd)
 }
 
 /*
- * Get the next zevent in the stream and place a copy in 'event'.
+ * Get the next zevent in the stream and place a copy in 'event'.  This
+ * may fail with ENOMEM if the encoded nvlist size exceeds the passed
+ * 'event_size'.  In this case the stream pointer is not advanced and
+ * and 'event_size' is set to the minimum required buffer size.
  */
 int
-zfs_zevent_next(zfs_zevent_t *ze, nvlist_t **event, uint64_t *dropped)
+zfs_zevent_next(zfs_zevent_t *ze, nvlist_t **event, uint64_t *event_size,
+                uint64_t *dropped)
 {
        zevent_t *ev;
-       int error;
+       size_t size;
+       int error = 0;
 
        mutex_enter(&zevent_lock);
        if (ze->ze_zevent == NULL) {
@@ -592,10 +597,18 @@ zfs_zevent_next(zfs_zevent_t *ze, nvlist_t **event, uint64_t *dropped)
                        error = ENOENT;
                        goto out;
                }
+       }
 
-               list_remove(&ze->ze_zevent->ev_ze_list, ze);
+       VERIFY(nvlist_size(ev->ev_nvl, &size, NV_ENCODE_NATIVE) == 0);
+       if (size > *event_size) {
+               *event_size = size;
+               error = ENOMEM;
+               goto out;
        }
 
+       if (ze->ze_zevent)
+               list_remove(&ze->ze_zevent->ev_ze_list, ze);
+
        ze->ze_zevent = ev;
        list_insert_head(&ev->ev_ze_list, ze);
        nvlist_dup(ev->ev_nvl, event, KM_SLEEP);
@@ -1475,8 +1488,8 @@ fm_init(void)
        zevent_len_cur = 0;
        zevent_flags = 0;
 
-       if (zevent_len_max == 0)
-               zevent_len_max = ERPT_MAX_ERRS * MAX(max_ncpus, 4);
+       if (zfs_zevent_len_max == 0)
+               zfs_zevent_len_max = ERPT_MAX_ERRS * MAX(max_ncpus, 4);
 
        /* Initialize zevent allocation and generation kstats */
        fm_ksp = kstat_create("zfs", 0, "fm", "misc", KSTAT_TYPE_NAMED,
@@ -1522,13 +1535,13 @@ fm_fini(void)
        }
 }
 
-module_param(zevent_len_max, int, 0644);
-MODULE_PARM_DESC(zevent_len_max, "Maximum event queue length");
+module_param(zfs_zevent_len_max, int, 0644);
+MODULE_PARM_DESC(zfs_zevent_len_max, "Max event queue length");
 
-module_param(zevent_cols, int, 0644);
-MODULE_PARM_DESC(zevent_cols, "Maximum event column width");
+module_param(zfs_zevent_cols, int, 0644);
+MODULE_PARM_DESC(zfs_zevent_cols, "Max event column width");
 
-module_param(zevent_console, int, 0644);
-MODULE_PARM_DESC(zevent_console, "Log events to the console");
+module_param(zfs_zevent_console, int, 0644);
+MODULE_PARM_DESC(zfs_zevent_console, "Log events to the console");
 
 #endif /* _KERNEL */