static int zfsdle_vdev_online(zpool_handle_t *zhp, void *data) { char *devname = data; boolean_t avail_spare, l2cache; vdev_state_t newstate; nvlist_t *tgt; zed_log_msg(LOG_INFO, "zfsdle_vdev_online: searching for '%s' in '%s'", devname, zpool_get_name(zhp)); if ((tgt = zpool_find_vdev_by_physpath(zhp, devname, &avail_spare, &l2cache, NULL)) != NULL) { char *path, fullpath[MAXPATHLEN]; uint64_t wholedisk = 0ULL; verify(nvlist_lookup_string(tgt, ZPOOL_CONFIG_PATH, &path) == 0); verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_WHOLE_DISK, &wholedisk) == 0); (void) strlcpy(fullpath, path, sizeof (fullpath)); if (wholedisk) { char *spath = zfs_strip_partition(fullpath); if (!spath) { zed_log_msg(LOG_INFO, "%s: Can't alloc", __func__); return (0); } (void) strlcpy(fullpath, spath, sizeof (fullpath)); free(spath); /* * We need to reopen the pool associated with this * device so that the kernel can update the size * of the expanded device. */ (void) zpool_reopen(zhp); } if (zpool_get_prop_int(zhp, ZPOOL_PROP_AUTOEXPAND, NULL)) { zed_log_msg(LOG_INFO, "zfsdle_vdev_online: setting " "device '%s' to ONLINE state in pool '%s'", fullpath, zpool_get_name(zhp)); if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL) (void) zpool_vdev_online(zhp, fullpath, 0, &newstate); } zpool_close(zhp); return (1); } zpool_close(zhp); return (0); }
/* * Iterate over all pools in the list, executing the callback for each */ int pool_list_iter(zpool_list_t *zlp, int unavail, zpool_iter_f func, void *data) { zpool_node_t *node, *next_node; int ret = 0; for (node = uu_avl_first(zlp->zl_avl); node != NULL; node = next_node) { next_node = uu_avl_next(zlp->zl_avl, node); if (zpool_get_state(node->zn_handle) != POOL_STATE_UNAVAIL || unavail) ret |= func(node->zn_handle, data); } return (ret); }
static int zfsdle_vdev_online(zpool_handle_t *zhp, void *data) { char *devname = data; boolean_t avail_spare, l2cache; vdev_state_t newstate; nvlist_t *tgt; syseventd_print(9, "zfsdle_vdev_online: searching for %s in pool %s\n", devname, zpool_get_name(zhp)); if ((tgt = zpool_find_vdev_by_physpath(zhp, devname, &avail_spare, &l2cache, NULL)) != NULL) { char *path, fullpath[MAXPATHLEN]; uint64_t wholedisk = 0ULL; verify(nvlist_lookup_string(tgt, ZPOOL_CONFIG_PATH, &path) == 0); verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_WHOLE_DISK, &wholedisk) == 0); (void) strlcpy(fullpath, path, sizeof (fullpath)); if (wholedisk) { fullpath[strlen(fullpath) - 2] = '\0'; /* * We need to reopen the pool associated with this * device so that the kernel can update the size * of the expanded device. */ (void) zpool_reopen(zhp); } if (zpool_get_prop_int(zhp, ZPOOL_PROP_AUTOEXPAND, NULL)) { syseventd_print(9, "zfsdle_vdev_online: setting device" " device %s to ONLINE state in pool %s.\n", fullpath, zpool_get_name(zhp)); if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL) (void) zpool_vdev_online(zhp, fullpath, 0, &newstate); } zpool_close(zhp); return (1); } zpool_close(zhp); return (0); }
int fmd_fmri_unusable(nvlist_t *nvl) { uint64_t pool_guid, vdev_guid; cbdata_t cb; nvlist_t *vd; int ret; (void) nvlist_lookup_uint64(nvl, FM_FMRI_ZFS_POOL, &pool_guid); cb.cb_guid = pool_guid; cb.cb_pool = NULL; if (zpool_iter(g_zfs, find_pool, &cb) != 1) return (1); if (nvlist_lookup_uint64(nvl, FM_FMRI_ZFS_VDEV, &vdev_guid) != 0) { ret = (zpool_get_state(cb.cb_pool) == POOL_STATE_UNAVAIL); zpool_close(cb.cb_pool); return (ret); } vd = find_vdev(cb.cb_pool, vdev_guid); if (vd == NULL) { ret = 1; } else { vdev_stat_t *vs; uint_t c; (void) nvlist_lookup_uint64_array(vd, ZPOOL_CONFIG_STATS, (uint64_t **)&vs, &c); ret = (vs->vs_state < VDEV_STATE_DEGRADED); } zpool_close(cb.cb_pool); return (ret); }
static int zfsdle_vdev_online(zpool_handle_t *zhp, void *data) { char *devname = data; boolean_t avail_spare, l2cache; nvlist_t *tgt; int error; zed_log_msg(LOG_INFO, "zfsdle_vdev_online: searching for '%s' in '%s'", devname, zpool_get_name(zhp)); if ((tgt = zpool_find_vdev_by_physpath(zhp, devname, &avail_spare, &l2cache, NULL)) != NULL) { char *path, fullpath[MAXPATHLEN]; uint64_t wholedisk; error = nvlist_lookup_string(tgt, ZPOOL_CONFIG_PATH, &path); if (error) { zpool_close(zhp); return (0); } error = nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_WHOLE_DISK, &wholedisk); if (error) wholedisk = 0; if (wholedisk) { path = strrchr(path, '/'); if (path != NULL) { path = zfs_strip_partition(path + 1); if (path == NULL) { zpool_close(zhp); return (0); } } else { zpool_close(zhp); return (0); } (void) strlcpy(fullpath, path, sizeof (fullpath)); free(path); /* * We need to reopen the pool associated with this * device so that the kernel can update the size of * the expanded device. When expanding there is no * need to restart the scrub from the beginning. */ boolean_t scrub_restart = B_FALSE; (void) zpool_reopen_one(zhp, &scrub_restart); } else { (void) strlcpy(fullpath, path, sizeof (fullpath)); } if (zpool_get_prop_int(zhp, ZPOOL_PROP_AUTOEXPAND, NULL)) { vdev_state_t newstate; if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL) { error = zpool_vdev_online(zhp, fullpath, 0, &newstate); zed_log_msg(LOG_INFO, "zfsdle_vdev_online: " "setting device '%s' to ONLINE state " "in pool '%s': %d", fullpath, zpool_get_name(zhp), error); } } zpool_close(zhp); return (1); } zpool_close(zhp); return (0); }
/* * Perform the import for the given configuration. This passes the heavy * lifting off to zpool_import_props(), and then mounts the datasets contained * within the pool. */ static int do_import(nvlist_t *config, const char *newname, const char *mntopts, nvlist_t *props, int flags) { zpool_handle_t *zhp; char *name; uint64_t state; uint64_t version; verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME, &name) == 0); verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE, &state) == 0); verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, &version) == 0); if (!SPA_VERSION_IS_SUPPORTED(version)) { printf("cannot import '%s': pool is formatted using an " "unsupported ZFS version\n", name); return (1); } else if (state != POOL_STATE_EXPORTED && !(flags & ZFS_IMPORT_ANY_HOST)) { uint64_t hostid; if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID, &hostid) == 0) { unsigned long system_hostid = gethostid() & 0xffffffff; if ((unsigned long)hostid != system_hostid) { char *hostname; uint64_t timestamp; time_t t; verify(nvlist_lookup_string(config, ZPOOL_CONFIG_HOSTNAME, &hostname) == 0); verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_TIMESTAMP, ×tamp) == 0); t = timestamp; printf("cannot import " "'%s': pool may be in " "use from other system, it was last " "accessed by %s (hostid: 0x%lx) on %s\n", name, hostname, (unsigned long)hostid, asctime(localtime(&t))); printf("use '-f' to import anyway\n"); return (1); } } else { printf("cannot import '%s': pool may be in use from " "other system\n", name); printf("use '-f' to import anyway\n"); return (1); } } if (zpool_import_props(g_zfs, config, newname, props, flags) != 0) return (1); if (newname != NULL) name = (char *)newname; if ((zhp = zpool_open_canfail(g_zfs, name)) == NULL) return (1); if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL && !(flags & ZFS_IMPORT_ONLY) && zpool_enable_datasets(zhp, mntopts, 0) != 0) { zpool_close(zhp); return (1); } zpool_close(zhp); return (0); }