diff options
author | Jorgen Lundman <[email protected]> | 2021-09-10 02:44:21 +0900 |
---|---|---|
committer | GitHub <[email protected]> | 2021-09-09 10:44:21 -0700 |
commit | 5a54a4e0517959dd917c0f78d692f7364e597a68 (patch) | |
tree | 1b8ea31a0f6bbb79fe9b8d62da80f3b1954a81ed | |
parent | 2079111f42a90b123f484337b43a549b7c5e50ba (diff) |
Upstream: Add snapshot and zvol events
For kernel to send snapshot mount/unmount events to zed.
For kernel to send symlink creates/removes on zvol plumbing.
(/dev/run/dsk/zvol/$pool/$zvol -> /dev/diskX)
If zed misses the ENODEV, all errors after are EINVAL. Treat any error
as kernel module failure.
Reviewed-by: Tony Hutter <[email protected]>
Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: Jorgen Lundman <[email protected]>
Closes #12416
-rw-r--r-- | cmd/zed/agents/zfs_retire.c | 1 | ||||
-rw-r--r-- | cmd/zed/zed.c | 2 | ||||
-rw-r--r-- | cmd/zed/zed_conf.c | 1 | ||||
-rw-r--r-- | cmd/zed/zed_exec.c | 2 | ||||
-rw-r--r-- | include/sys/fm/fs/zfs.h | 9 | ||||
-rw-r--r-- | include/sys/spa.h | 2 | ||||
-rw-r--r-- | include/sys/zio.h | 2 | ||||
-rw-r--r-- | module/zfs/zfs_fm.c | 52 |
8 files changed, 70 insertions, 1 deletions
diff --git a/cmd/zed/agents/zfs_retire.c b/cmd/zed/agents/zfs_retire.c index 1563f5d27..6c009bdc1 100644 --- a/cmd/zed/agents/zfs_retire.c +++ b/cmd/zed/agents/zfs_retire.c @@ -41,6 +41,7 @@ #include <libzutil.h> #include <libzfs.h> #include <string.h> +#include <libgen.h> #include "zfs_agents.h" #include "fmd_api.h" diff --git a/cmd/zed/zed.c b/cmd/zed/zed.c index 0aa03fded..e45176c00 100644 --- a/cmd/zed/zed.c +++ b/cmd/zed/zed.c @@ -291,7 +291,7 @@ idle: rv = zed_event_service(&zcp); /* ENODEV: When kernel module is unloaded (osx) */ - if (rv == ENODEV) + if (rv != 0) break; } diff --git a/cmd/zed/zed_conf.c b/cmd/zed/zed_conf.c index 2cf2311db..59935102f 100644 --- a/cmd/zed/zed_conf.c +++ b/cmd/zed/zed_conf.c @@ -22,6 +22,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <sys/types.h> #include <sys/stat.h> #include <sys/uio.h> #include <unistd.h> diff --git a/cmd/zed/zed_exec.c b/cmd/zed/zed_exec.c index 1eecfa0a9..03dcd03ac 100644 --- a/cmd/zed/zed_exec.c +++ b/cmd/zed/zed_exec.c @@ -26,6 +26,8 @@ #include <time.h> #include <unistd.h> #include <pthread.h> +#include <signal.h> + #include "zed_exec.h" #include "zed_log.h" #include "zed_strings.h" diff --git a/include/sys/fm/fs/zfs.h b/include/sys/fm/fs/zfs.h index 6491606d3..cd080c8ee 100644 --- a/include/sys/fm/fs/zfs.h +++ b/include/sys/fm/fs/zfs.h @@ -110,6 +110,10 @@ extern "C" { #define FM_EREPORT_PAYLOAD_ZFS_BAD_CLEARED_BITS "bad_cleared_bits" #define FM_EREPORT_PAYLOAD_ZFS_BAD_SET_HISTOGRAM "bad_set_histogram" #define FM_EREPORT_PAYLOAD_ZFS_BAD_CLEARED_HISTOGRAM "bad_cleared_histogram" +#define FM_EREPORT_PAYLOAD_ZFS_SNAPSHOT_NAME "snapshot_name" +#define FM_EREPORT_PAYLOAD_ZFS_DEVICE_NAME "device_name" +#define FM_EREPORT_PAYLOAD_ZFS_RAW_DEVICE_NAME "raw_name" +#define FM_EREPORT_PAYLOAD_ZFS_VOLUME "volume" #define FM_EREPORT_FAILMODE_WAIT "wait" #define FM_EREPORT_FAILMODE_CONTINUE "continue" @@ -119,6 +123,11 @@ extern "C" { #define FM_RESOURCE_AUTOREPLACE "autoreplace" #define FM_RESOURCE_STATECHANGE "statechange" +#define FM_RESOURCE_ZFS_SNAPSHOT_MOUNT "snapshot_mount" +#define FM_RESOURCE_ZFS_SNAPSHOT_UNMOUNT "snapshot_unmount" +#define FM_RESOURCE_ZVOL_CREATE_SYMLINK "zvol_create" +#define FM_RESOURCE_ZVOL_REMOVE_SYMLINK "zvol_remove" + #ifdef __cplusplus } #endif diff --git a/include/sys/spa.h b/include/sys/spa.h index f811d6f5a..2ae467877 100644 --- a/include/sys/spa.h +++ b/include/sys/spa.h @@ -1170,6 +1170,8 @@ extern void spa_configfile_set(spa_t *, nvlist_t *, boolean_t); /* asynchronous event notification */ extern void spa_event_notify(spa_t *spa, vdev_t *vdev, nvlist_t *hist_nvl, const char *name); +extern void zfs_ereport_zvol_post(const char *subclass, const char *name, + const char *device_name, const char *raw_name); /* waiting for pool activities to complete */ extern int spa_wait(const char *pool, zpool_wait_activity_t activity, diff --git a/include/sys/zio.h b/include/sys/zio.h index 2d34481f6..5b606eaf8 100644 --- a/include/sys/zio.h +++ b/include/sys/zio.h @@ -673,6 +673,8 @@ extern int zfs_ereport_post_checksum(spa_t *spa, vdev_t *vd, struct zio_bad_cksum *info); void zio_vsd_default_cksum_report(zio_t *zio, zio_cksum_report_t *zcr); +extern void zfs_ereport_snapshot_post(const char *subclass, spa_t *spa, + const char *name); /* Called from spa_sync(), but primarily an injection handler */ extern void spa_handle_ignored_writes(spa_t *spa); diff --git a/module/zfs/zfs_fm.c b/module/zfs/zfs_fm.c index 60e631567..007f31b4e 100644 --- a/module/zfs/zfs_fm.c +++ b/module/zfs/zfs_fm.c @@ -1444,6 +1444,58 @@ zfs_ereport_fini(void) mutex_destroy(&recent_events_lock); } +void +zfs_ereport_snapshot_post(const char *subclass, spa_t *spa, const char *name) +{ + nvlist_t *aux; + + aux = fm_nvlist_create(NULL); + nvlist_add_string(aux, FM_EREPORT_PAYLOAD_ZFS_SNAPSHOT_NAME, name); + + zfs_post_common(spa, NULL, FM_RSRC_CLASS, subclass, aux); + fm_nvlist_destroy(aux, FM_NVA_FREE); +} + +/* + * Post when a event when a zvol is created or removed + * + * This is currently only used by macOS, since it uses the event to create + * symlinks between the volume name (mypool/myvol) and the actual /dev + * device (/dev/disk3). For example: + * + * /var/run/zfs/dsk/mypool/myvol -> /dev/disk3 + * + * name: The full name of the zvol ("mypool/myvol") + * dev_name: The full /dev name for the zvol ("/dev/disk3") + * raw_name: The raw /dev name for the zvol ("/dev/rdisk3") + */ +void +zfs_ereport_zvol_post(const char *subclass, const char *name, + const char *dev_name, const char *raw_name) +{ + nvlist_t *aux; + char *r; + + boolean_t locked = mutex_owned(&spa_namespace_lock); + if (!locked) mutex_enter(&spa_namespace_lock); + spa_t *spa = spa_lookup(name); + if (!locked) mutex_exit(&spa_namespace_lock); + + if (spa == NULL) + return; + + aux = fm_nvlist_create(NULL); + nvlist_add_string(aux, FM_EREPORT_PAYLOAD_ZFS_DEVICE_NAME, dev_name); + nvlist_add_string(aux, FM_EREPORT_PAYLOAD_ZFS_RAW_DEVICE_NAME, + raw_name); + r = strchr(name, '/'); + if (r && r[1]) + nvlist_add_string(aux, FM_EREPORT_PAYLOAD_ZFS_VOLUME, &r[1]); + + zfs_post_common(spa, NULL, FM_RSRC_CLASS, subclass, aux); + fm_nvlist_destroy(aux, FM_NVA_FREE); +} + EXPORT_SYMBOL(zfs_ereport_post); EXPORT_SYMBOL(zfs_ereport_is_valid); EXPORT_SYMBOL(zfs_ereport_post_checksum); |