Ejemplo n.º 1
0
boolean_t
zfeature_is_supported(const char *guid)
{
	if (zfeature_checks_disable)
		return (B_TRUE);

	return (0 == zfeature_lookup_guid(guid, NULL));
}
Ejemplo n.º 2
0
static void
zhack_do_feature_ref(int argc, char **argv)
{
	char c;
	char *target;
	boolean_t decr = B_FALSE;
	spa_t *spa;
	objset_t *mos;
	zfeature_info_t feature;
	zfeature_info_t *nodeps[] = { NULL };

	/*
	 * fi_desc does not matter here because it was written to disk
	 * when the feature was enabled, but we need to properly set the
	 * feature for read or write based on the information we read off
	 * disk later.
	 */
	feature.fi_uname = "zhack";
	feature.fi_mos = B_FALSE;
	feature.fi_desc = NULL;
	feature.fi_depends = nodeps;

	optind = 1;
	while ((c = getopt(argc, argv, "md")) != -1) {
		switch (c) {
		case 'm':
			feature.fi_mos = B_TRUE;
			break;
		case 'd':
			decr = B_TRUE;
			break;
		default:
			usage();
			break;
		}
	}
	argc -= optind;
	argv += optind;

	if (argc < 2) {
		(void) fprintf(stderr, "error: missing feature or pool name\n");
		usage();
	}
	target = argv[0];
	feature.fi_guid = argv[1];

	if (!zfeature_is_valid_guid(feature.fi_guid))
		fatal("invalid feature guid: %s", feature.fi_guid);

	zhack_spa_open(target, B_FALSE, FTAG, &spa);
	mos = spa->spa_meta_objset;

	if (0 == zfeature_lookup_guid(feature.fi_guid, NULL))
		fatal("'%s' is a real feature, will not change refcount");

	if (0 == zap_contains(mos, spa->spa_feat_for_read_obj,
	    feature.fi_guid)) {
		feature.fi_can_readonly = B_FALSE;
	} else if (0 == zap_contains(mos, spa->spa_feat_for_write_obj,
	    feature.fi_guid)) {
		feature.fi_can_readonly = B_TRUE;
	} else {
		fatal("feature is not enabled: %s", feature.fi_guid);
	}

	if (decr && !spa_feature_is_active(spa, &feature))
		fatal("feature refcount already 0: %s", feature.fi_guid);

	VERIFY0(dsl_sync_task(spa_name(spa), NULL,
	    decr ? feature_decr_sync : feature_incr_sync, &feature, 5));

	spa_close(spa, FTAG);
}
Ejemplo n.º 3
0
static void
zhack_do_feature_enable(int argc, char **argv)
{
	char c;
	char *desc, *target;
	spa_t *spa;
	objset_t *mos;
	zfeature_info_t feature;
	zfeature_info_t *nodeps[] = { NULL };

	/*
	 * Features are not added to the pool's label until their refcounts
	 * are incremented, so fi_mos can just be left as false for now.
	 */
	desc = NULL;
	feature.fi_uname = "zhack";
	feature.fi_mos = B_FALSE;
	feature.fi_can_readonly = B_FALSE;
	feature.fi_depends = nodeps;

	optind = 1;
	while ((c = getopt(argc, argv, "rmd:")) != -1) {
		switch (c) {
		case 'r':
			feature.fi_can_readonly = B_TRUE;
			break;
		case 'd':
			desc = strdup(optarg);
			break;
		default:
			usage();
			break;
		}
	}

	if (desc == NULL)
		desc = strdup("zhack injected");
	feature.fi_desc = desc;

	argc -= optind;
	argv += optind;

	if (argc < 2) {
		(void) fprintf(stderr, "error: missing feature or pool name\n");
		usage();
	}
	target = argv[0];
	feature.fi_guid = argv[1];

	if (!zfeature_is_valid_guid(feature.fi_guid))
		fatal("invalid feature guid: %s", feature.fi_guid);

	zhack_spa_open(target, B_FALSE, FTAG, &spa);
	mos = spa->spa_meta_objset;

	if (0 == zfeature_lookup_guid(feature.fi_guid, NULL))
		fatal("'%s' is a real feature, will not enable");
	if (0 == zap_contains(mos, spa->spa_feat_desc_obj, feature.fi_guid))
		fatal("feature already enabled: %s", feature.fi_guid);

	VERIFY0(dsl_sync_task(spa_name(spa), NULL,
	    feature_enable_sync, &feature, 5));

	spa_close(spa, FTAG);

	free(desc);
}