コード例 #1
0
int
zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *propbuf,
    size_t proplen, zfs_source_t *srctype)
{
	uint64_t value;
	char msg[1024], *strvalue;
	nvlist_t *nvp;
	zfs_source_t src = ZFS_SRC_NONE;

	(void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
	    "cannot get property '%s'"), zpool_prop_to_name(prop));

	if (zpool_get_version(zhp) < ZFS_VERSION_BOOTFS) {
		zfs_error_aux(zhp->zpool_hdl,
		    dgettext(TEXT_DOMAIN, "pool must be "
		    "upgraded to support pool properties"));
		return (zfs_error(zhp->zpool_hdl, EZFS_BADVERSION, msg));
	}

	if (zhp->zpool_props == NULL && zpool_get_all_props(zhp))
		return (zfs_error(zhp->zpool_hdl, EZFS_POOLPROPS, msg));

	/*
	 * the "name" property is special cased
	 */
	if (!zfs_prop_valid_for_type(prop, ZFS_TYPE_POOL) &&
	    prop != ZFS_PROP_NAME)
		return (-1);

	switch (prop) {
	case ZFS_PROP_NAME:
		(void) strlcpy(propbuf, zhp->zpool_name, proplen);
		break;

	case ZFS_PROP_BOOTFS:
		if (nvlist_lookup_nvlist(zhp->zpool_props,
		    zpool_prop_to_name(prop), &nvp) != 0) {
			strvalue = (char *)zfs_prop_default_string(prop);
			if (strvalue == NULL)
				strvalue = "-";
			src = ZFS_SRC_DEFAULT;
		} else {
			VERIFY(nvlist_lookup_uint64(nvp,
			    ZFS_PROP_SOURCE, &value) == 0);
			src = value;
			VERIFY(nvlist_lookup_string(nvp, ZFS_PROP_VALUE,
			    &strvalue) == 0);
			if (strlen(strvalue) >= proplen)
				return (-1);
		}
		(void) strcpy(propbuf, strvalue);
		break;

	default:
		return (-1);
	}
	if (srctype)
		*srctype = src;
	return (0);
}
コード例 #2
0
int
zpool_set_prop(zpool_handle_t *zhp, const char *propname, const char *propval)
{
	zfs_cmd_t zc = { 0 };
	int ret = -1;
	char errbuf[1024];
	nvlist_t *nvl = NULL;
	nvlist_t *realprops;

	(void) snprintf(errbuf, sizeof (errbuf),
	    dgettext(TEXT_DOMAIN, "cannot set property for '%s'"),
	    zhp->zpool_name);

	if (zpool_get_version(zhp) < ZFS_VERSION_BOOTFS) {
		zfs_error_aux(zhp->zpool_hdl,
		    dgettext(TEXT_DOMAIN, "pool must be "
		    "upgraded to support pool properties"));
		return (zfs_error(zhp->zpool_hdl, EZFS_BADVERSION, errbuf));
	}

	if (zhp->zpool_props == NULL && zpool_get_all_props(zhp))
		return (zfs_error(zhp->zpool_hdl, EZFS_POOLPROPS, errbuf));

	if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0 ||
	    nvlist_add_string(nvl, propname, propval) != 0) {
		return (no_memory(zhp->zpool_hdl));
	}

	if ((realprops = zfs_validate_properties(zhp->zpool_hdl, ZFS_TYPE_POOL,
	    zhp->zpool_name, nvl, 0, NULL, errbuf)) == NULL) {
		nvlist_free(nvl);
		return (-1);
	}

	nvlist_free(nvl);
	nvl = realprops;

	/*
	 * Execute the corresponding ioctl() to set this property.
	 */
	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));

	if (zcmd_write_src_nvlist(zhp->zpool_hdl, &zc, nvl, NULL) != 0)
		return (-1);

	ret = ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_POOL_SET_PROPS, &zc);
	zcmd_free_nvlists(&zc);

	if (ret)
		(void) zpool_standard_error(zhp->zpool_hdl, errno, errbuf);

	return (ret);
}
コード例 #3
0
ファイル: libzfs_pool.c プロジェクト: andreiw/polaris
/*
 * Add the given vdevs to the pool.  The caller must have already performed the
 * necessary verification to ensure that the vdev specification is well-formed.
 */
int
zpool_add(zpool_handle_t *zhp, nvlist_t *nvroot)
{
	char *packed;
	size_t len;
	zfs_cmd_t zc;
	int ret;
	libzfs_handle_t *hdl = zhp->zpool_hdl;
	char msg[1024];
	nvlist_t **spares;
	uint_t nspares;

	(void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
	    "cannot add to '%s'"), zhp->zpool_name);

	if (zpool_get_version(zhp) < ZFS_VERSION_SPARES &&
	    nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
	    &spares, &nspares) == 0) {
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool must be "
		    "upgraded to add hot spares"));
		return (zfs_error(hdl, EZFS_BADVERSION, msg));
	}

	verify(nvlist_size(nvroot, &len, NV_ENCODE_NATIVE) == 0);

	if ((packed = zfs_alloc(zhp->zpool_hdl, len)) == NULL)
		return (-1);

	verify(nvlist_pack(nvroot, &packed, &len, NV_ENCODE_NATIVE, 0) == 0);

	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
	zc.zc_config_src = (uint64_t)(uintptr_t)packed;
	zc.zc_config_src_size = len;

	if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_VDEV_ADD, &zc) != 0) {
		switch (errno) {
		case EBUSY:
			/*
			 * This can happen if the user has specified the same
			 * device multiple times.  We can't reliably detect this
			 * until we try to add it and see we already have a
			 * label.
			 */
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "one or more vdevs refer to the same device"));
			(void) zfs_error(hdl, EZFS_BADDEV, msg);
			break;

		case EOVERFLOW:
			/*
			 * This occurrs when one of the devices is below
			 * SPA_MINDEVSIZE.  Unfortunately, we can't detect which
			 * device was the problem device since there's no
			 * reliable way to determine device size from userland.
			 */
			{
				char buf[64];

				zfs_nicenum(SPA_MINDEVSIZE, buf, sizeof (buf));

				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
				    "device is less than the minimum "
				    "size (%s)"), buf);
			}
			(void) zfs_error(hdl, EZFS_BADDEV, msg);
			break;

		case ENOTSUP:
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "pool must be upgraded to add raidz2 vdevs"));
			(void) zfs_error(hdl, EZFS_BADVERSION, msg);
			break;

		default:
			(void) zpool_standard_error(hdl, errno, msg);
		}

		ret = -1;
	} else {
		ret = 0;
	}

	free(packed);

	return (ret);
}