示例#1
0
文件: zfs_mod.c 项目: behlendorf/zfs
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);
}
示例#2
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);
}
示例#3
0
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);
}
示例#4
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);
}
示例#5
0
文件: zfs_mod.c 项目: DeHackEd/zfs
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);
}
示例#6
0
文件: zfs_util.c 项目: derzzle/zfs
/*
 * 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, &timestamp) == 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);
}