diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/cmd/syseventd/modules/zfs_mod/zfs_mod.c | 140 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/spa.c | 18 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/vdev.c | 9 | ||||
-rw-r--r-- | usr/src/uts/common/sys/sysevent/eventdefs.h | 7 |
4 files changed, 157 insertions, 17 deletions
diff --git a/usr/src/cmd/syseventd/modules/zfs_mod/zfs_mod.c b/usr/src/cmd/syseventd/modules/zfs_mod/zfs_mod.c index 8fff5c748a..87b4e2995d 100644 --- a/usr/src/cmd/syseventd/modules/zfs_mod/zfs_mod.c +++ b/usr/src/cmd/syseventd/modules/zfs_mod/zfs_mod.c @@ -21,7 +21,7 @@ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012 by Delphix. All rights reserved. - * Copyright 2014 Nexenta Systems, Inc. All rights reserved. + * Copyright 2015 Nexenta Systems, Inc. All rights reserved. */ /* @@ -297,7 +297,7 @@ zfs_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *data) if (nvlist_lookup_uint64(nvl, ZPOOL_CONFIG_GUID, &guid) != 0 || guid != dp->dd_vdev_guid) return; - } else { + } else if (dp->dd_compare != NULL) { len = strlen(dp->dd_compare); if (nvlist_lookup_string(nvl, dp->dd_prop, &path) != 0 || @@ -585,6 +585,109 @@ zfsdle_vdev_online(zpool_handle_t *zhp, void *data) return (0); } +/* + * This function is called for each vdev of a pool for which any of the + * following events was recieved: + * - ESC_ZFS_vdev_add + * - ESC_ZFS_vdev_attach + * - ESC_ZFS_vdev_clear + * - ESC_ZFS_vdev_online + * - ESC_ZFS_pool_create + * - ESC_ZFS_pool_import + * It will update the vdevs FRU property if it is out of date. + */ +/*ARGSUSED2*/ +static void +zfs_update_vdev_fru(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t isdisk) +{ + char *devpath, *cptr, *oldfru = NULL; + const char *newfru; + uint64_t vdev_guid; + + (void) nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_GUID, &vdev_guid); + (void) nvlist_lookup_string(vdev, ZPOOL_CONFIG_PHYS_PATH, &devpath); + (void) nvlist_lookup_string(vdev, ZPOOL_CONFIG_FRU, &oldfru); + + /* remove :<slice> from devpath */ + cptr = strrchr(devpath, ':'); + if (cptr != NULL) + *cptr = '\0'; + + newfru = libzfs_fru_lookup(g_zfshdl, devpath); + if (newfru == NULL) { + syseventd_print(9, "zfs_update_vdev_fru: no FRU for %s\n", + devpath); + return; + } + + /* do nothing if the FRU hasn't changed */ + if (oldfru != NULL && libzfs_fru_compare(g_zfshdl, oldfru, newfru)) { + syseventd_print(9, "zfs_update_vdev_fru: FRU unchanged\n"); + return; + } + + syseventd_print(9, "zfs_update_vdev_fru: devpath = %s\n", devpath); + syseventd_print(9, "zfs_update_vdev_fru: FRU = %s\n", newfru); + + (void) zpool_fru_set(zhp, vdev_guid, newfru); +} + +/* + * This function handles the following events: + * - ESC_ZFS_vdev_add + * - ESC_ZFS_vdev_attach + * - ESC_ZFS_vdev_clear + * - ESC_ZFS_vdev_online + * - ESC_ZFS_pool_create + * - ESC_ZFS_pool_import + * It will iterate over the pool vdevs to update the FRU property. + */ +int +zfs_deliver_update(nvlist_t *nvl) +{ + dev_data_t dd = { 0 }; + char *pname; + zpool_handle_t *zhp; + nvlist_t *config, *vdev; + + if (nvlist_lookup_string(nvl, "pool_name", &pname) != 0) { + syseventd_print(9, "zfs_deliver_update: no pool name\n"); + return (-1); + } + + /* + * If this event was triggered by a pool export or destroy we cannot + * open the pool. This is not an error, just return 0 as we don't care + * about these events. + */ + zhp = zpool_open_canfail(g_zfshdl, pname); + if (zhp == NULL) + return (0); + + config = zpool_get_config(zhp, NULL); + if (config == NULL) { + syseventd_print(9, "zfs_deliver_update: " + "failed to get pool config for %s\n", pname); + zpool_close(zhp); + return (-1); + } + + if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, &vdev) != 0) { + syseventd_print(0, "zfs_deliver_update: " + "failed to get vdev tree for %s\n", pname); + zpool_close(zhp); + return (-1); + } + + libzfs_fru_refresh(g_zfshdl); + + dd.dd_func = zfs_update_vdev_fru; + zfs_iter_vdev(zhp, vdev, &dd); + + zpool_close(zhp); + return (0); +} + int zfs_deliver_dle(nvlist_t *nvl) { @@ -622,7 +725,8 @@ zfs_deliver_event(sysevent_t *ev, int unused) const char *subclass = sysevent_get_subclass_name(ev); nvlist_t *nvl; int ret; - boolean_t is_lofi, is_check, is_dle = B_FALSE; + boolean_t is_lofi = B_FALSE, is_check = B_FALSE; + boolean_t is_dle = B_FALSE, is_update = B_FALSE; if (strcmp(class, EC_DEV_ADD) == 0) { /* @@ -637,14 +741,26 @@ zfs_deliver_event(sysevent_t *ev, int unused) return (0); is_check = B_FALSE; - } else if (strcmp(class, EC_ZFS) == 0 && - strcmp(subclass, ESC_ZFS_VDEV_CHECK) == 0) { - /* - * This event signifies that a device failed to open during pool - * load, but the 'autoreplace' property was set, so we should - * pretend it's just been added. - */ - is_check = B_TRUE; + } else if (strcmp(class, EC_ZFS) == 0) { + if (strcmp(subclass, ESC_ZFS_VDEV_CHECK) == 0) { + /* + * This event signifies that a device failed to open + * during pool load, but the 'autoreplace' property was + * set, so we should pretend it's just been added. + */ + is_check = B_TRUE; + } else if ((strcmp(subclass, ESC_ZFS_VDEV_ADD) == 0) || + (strcmp(subclass, ESC_ZFS_VDEV_ATTACH) == 0) || + (strcmp(subclass, ESC_ZFS_VDEV_CLEAR) == 0) || + (strcmp(subclass, ESC_ZFS_VDEV_ONLINE) == 0) || + (strcmp(subclass, ESC_ZFS_POOL_CREATE) == 0) || + (strcmp(subclass, ESC_ZFS_POOL_IMPORT) == 0)) { + /* + * When we receive these events we check the pool + * configuration and update the vdev FRUs if necessary. + */ + is_update = B_TRUE; + } } else if (strcmp(class, EC_DEV_STATUS) == 0 && strcmp(subclass, ESC_DEV_DLE) == 0) { is_dle = B_TRUE; @@ -657,6 +773,8 @@ zfs_deliver_event(sysevent_t *ev, int unused) if (is_dle) ret = zfs_deliver_dle(nvl); + else if (is_update) + ret = zfs_deliver_update(nvl); else if (is_check) ret = zfs_deliver_check(nvl); else diff --git a/usr/src/uts/common/fs/zfs/spa.c b/usr/src/uts/common/fs/zfs/spa.c index 5e664d7d61..537c0945d1 100644 --- a/usr/src/uts/common/fs/zfs/spa.c +++ b/usr/src/uts/common/fs/zfs/spa.c @@ -22,7 +22,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2014 by Delphix. All rights reserved. - * Copyright (c) 2013, 2014, Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2015, Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved. */ @@ -3689,6 +3689,7 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props, txg_wait_synced(spa->spa_dsl_pool, txg); spa_config_sync(spa, B_FALSE, B_TRUE); + spa_event_notify(spa, NULL, ESC_ZFS_POOL_CREATE); spa_history_log_version(spa, "create"); @@ -3954,6 +3955,7 @@ spa_import(const char *pool, nvlist_t *config, nvlist_t *props, uint64_t flags) spa_configfile_set(spa, props, B_FALSE); spa_config_sync(spa, B_FALSE, B_TRUE); + spa_event_notify(spa, NULL, ESC_ZFS_POOL_IMPORT); mutex_exit(&spa_namespace_lock); return (0); @@ -4084,9 +4086,12 @@ spa_import(const char *pool, nvlist_t *config, nvlist_t *props, uint64_t flags) */ spa_async_request(spa, SPA_ASYNC_AUTOEXPAND); - mutex_exit(&spa_namespace_lock); spa_history_log_version(spa, "import"); + spa_event_notify(spa, NULL, ESC_ZFS_POOL_IMPORT); + + mutex_exit(&spa_namespace_lock); + return (0); } @@ -4427,6 +4432,7 @@ spa_vdev_add(spa_t *spa, nvlist_t *nvroot) mutex_enter(&spa_namespace_lock); spa_config_update(spa, SPA_CONFIG_UPDATE_POOL); + spa_event_notify(spa, NULL, ESC_ZFS_VDEV_ADD); mutex_exit(&spa_namespace_lock); return (0); @@ -4621,6 +4627,11 @@ spa_vdev_attach(spa_t *spa, uint64_t guid, nvlist_t *nvroot, int replacing) */ dsl_resilver_restart(spa->spa_dsl_pool, dtl_max_txg); + if (spa->spa_bootfs) + spa_event_notify(spa, newvd, ESC_ZFS_BOOTFS_VDEV_ATTACH); + + spa_event_notify(spa, newvd, ESC_ZFS_VDEV_ATTACH); + /* * Commit the config */ @@ -4635,9 +4646,6 @@ spa_vdev_attach(spa_t *spa, uint64_t guid, nvlist_t *nvroot, int replacing) spa_strfree(oldvdpath); spa_strfree(newvdpath); - if (spa->spa_bootfs) - spa_event_notify(spa, newvd, ESC_ZFS_BOOTFS_VDEV_ATTACH); - return (0); } diff --git a/usr/src/uts/common/fs/zfs/vdev.c b/usr/src/uts/common/fs/zfs/vdev.c index 9e27578f8e..1c57fce4dc 100644 --- a/usr/src/uts/common/fs/zfs/vdev.c +++ b/usr/src/uts/common/fs/zfs/vdev.c @@ -2357,6 +2357,7 @@ int vdev_online(spa_t *spa, uint64_t guid, uint64_t flags, vdev_state_t *newstate) { vdev_t *vd, *tvd, *pvd, *rvd = spa->spa_root_vdev; + boolean_t postevent = B_FALSE; spa_vdev_state_enter(spa, SCL_NONE); @@ -2366,6 +2367,10 @@ vdev_online(spa_t *spa, uint64_t guid, uint64_t flags, vdev_state_t *newstate) if (!vd->vdev_ops->vdev_op_leaf) return (spa_vdev_state_exit(spa, NULL, ENOTSUP)); + postevent = + (vd->vdev_offline == B_TRUE || vd->vdev_tmpoffline == B_TRUE) ? + B_TRUE : B_FALSE; + tvd = vd->vdev_top; vd->vdev_offline = B_FALSE; vd->vdev_tmpoffline = B_FALSE; @@ -2401,6 +2406,10 @@ vdev_online(spa_t *spa, uint64_t guid, uint64_t flags, vdev_state_t *newstate) return (spa_vdev_state_exit(spa, vd, ENOTSUP)); spa_async_request(spa, SPA_ASYNC_CONFIG_UPDATE); } + + if (postevent) + spa_event_notify(spa, vd, ESC_ZFS_VDEV_ONLINE); + return (spa_vdev_state_exit(spa, vd, 0)); } diff --git a/usr/src/uts/common/sys/sysevent/eventdefs.h b/usr/src/uts/common/sys/sysevent/eventdefs.h index 5a75c5d844..9c6907a08a 100644 --- a/usr/src/uts/common/sys/sysevent/eventdefs.h +++ b/usr/src/uts/common/sys/sysevent/eventdefs.h @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright 2015 Nexenta Systems, Inc. All rights reserved. */ #ifndef _SYS_SYSEVENT_EVENTDEFS_H @@ -249,9 +249,14 @@ extern "C" { #define ESC_ZFS_RESILVER_START "ESC_ZFS_resilver_start" #define ESC_ZFS_RESILVER_FINISH "ESC_ZFS_resilver_finish" #define ESC_ZFS_VDEV_REMOVE "ESC_ZFS_vdev_remove" +#define ESC_ZFS_POOL_CREATE "ESC_ZFS_pool_create" #define ESC_ZFS_POOL_DESTROY "ESC_ZFS_pool_destroy" +#define ESC_ZFS_POOL_IMPORT "ESC_ZFS_pool_import" +#define ESC_ZFS_VDEV_ADD "ESC_ZFS_vdev_add" +#define ESC_ZFS_VDEV_ATTACH "ESC_ZFS_vdev_attach" #define ESC_ZFS_VDEV_CLEAR "ESC_ZFS_vdev_clear" #define ESC_ZFS_VDEV_CHECK "ESC_ZFS_vdev_check" +#define ESC_ZFS_VDEV_ONLINE "ESC_ZFS_vdev_online" #define ESC_ZFS_CONFIG_SYNC "ESC_ZFS_config_sync" #define ESC_ZFS_SCRUB_START "ESC_ZFS_scrub_start" #define ESC_ZFS_SCRUB_FINISH "ESC_ZFS_scrub_finish" |