327 argv += optind;
328
329 if (argc < 2) {
330 (void) fprintf(stderr, "error: missing feature or pool name\n");
331 usage();
332 }
333 target = argv[0];
334 feature.fi_guid = argv[1];
335
336 if (!zfeature_is_valid_guid(feature.fi_guid))
337 fatal("invalid feature guid: %s", feature.fi_guid);
338
339 zhack_spa_open(target, B_FALSE, FTAG, &spa);
340 mos = spa->spa_meta_objset;
341
342 if (0 == zfeature_lookup_guid(feature.fi_guid, NULL))
343 fatal("'%s' is a real feature, will not enable");
344 if (0 == zap_contains(mos, spa->spa_feat_desc_obj, feature.fi_guid))
345 fatal("feature already enabled: %s", feature.fi_guid);
346
347 VERIFY3U(0, ==, dsl_sync_task_do(spa->spa_dsl_pool, NULL,
348 feature_enable_sync, spa, &feature, 5));
349
350 spa_close(spa, FTAG);
351
352 free(desc);
353 }
354
355 static void
356 feature_incr_sync(void *arg1, void *arg2, dmu_tx_t *tx)
357 {
358 spa_t *spa = arg1;
359 zfeature_info_t *feature = arg2;
360
361 spa_feature_incr(spa, feature, tx);
362 spa_history_log_internal(spa, "zhack feature incr", tx,
363 "name=%s", feature->fi_guid);
364 }
365
366 static void
367 feature_decr_sync(void *arg1, void *arg2, dmu_tx_t *tx)
425
426 zhack_spa_open(target, B_FALSE, FTAG, &spa);
427 mos = spa->spa_meta_objset;
428
429 if (0 == zfeature_lookup_guid(feature.fi_guid, NULL))
430 fatal("'%s' is a real feature, will not change refcount");
431
432 if (0 == zap_contains(mos, spa->spa_feat_for_read_obj,
433 feature.fi_guid)) {
434 feature.fi_can_readonly = B_FALSE;
435 } else if (0 == zap_contains(mos, spa->spa_feat_for_write_obj,
436 feature.fi_guid)) {
437 feature.fi_can_readonly = B_TRUE;
438 } else {
439 fatal("feature is not enabled: %s", feature.fi_guid);
440 }
441
442 if (decr && !spa_feature_is_active(spa, &feature))
443 fatal("feature refcount already 0: %s", feature.fi_guid);
444
445 VERIFY3U(0, ==, dsl_sync_task_do(spa->spa_dsl_pool, NULL,
446 decr ? feature_decr_sync : feature_incr_sync, spa, &feature, 5));
447
448 spa_close(spa, FTAG);
449 }
450
451 static int
452 zhack_do_feature(int argc, char **argv)
453 {
454 char *subcommand;
455
456 argc--;
457 argv++;
458 if (argc == 0) {
459 (void) fprintf(stderr,
460 "error: no feature operation specified\n");
461 usage();
462 }
463
464 subcommand = argv[0];
465 if (strcmp(subcommand, "stat") == 0) {
|
327 argv += optind;
328
329 if (argc < 2) {
330 (void) fprintf(stderr, "error: missing feature or pool name\n");
331 usage();
332 }
333 target = argv[0];
334 feature.fi_guid = argv[1];
335
336 if (!zfeature_is_valid_guid(feature.fi_guid))
337 fatal("invalid feature guid: %s", feature.fi_guid);
338
339 zhack_spa_open(target, B_FALSE, FTAG, &spa);
340 mos = spa->spa_meta_objset;
341
342 if (0 == zfeature_lookup_guid(feature.fi_guid, NULL))
343 fatal("'%s' is a real feature, will not enable");
344 if (0 == zap_contains(mos, spa->spa_feat_desc_obj, feature.fi_guid))
345 fatal("feature already enabled: %s", feature.fi_guid);
346
347 VERIFY0(dsl_sync_task_do(spa->spa_dsl_pool, NULL,
348 feature_enable_sync, spa, &feature, 5));
349
350 spa_close(spa, FTAG);
351
352 free(desc);
353 }
354
355 static void
356 feature_incr_sync(void *arg1, void *arg2, dmu_tx_t *tx)
357 {
358 spa_t *spa = arg1;
359 zfeature_info_t *feature = arg2;
360
361 spa_feature_incr(spa, feature, tx);
362 spa_history_log_internal(spa, "zhack feature incr", tx,
363 "name=%s", feature->fi_guid);
364 }
365
366 static void
367 feature_decr_sync(void *arg1, void *arg2, dmu_tx_t *tx)
425
426 zhack_spa_open(target, B_FALSE, FTAG, &spa);
427 mos = spa->spa_meta_objset;
428
429 if (0 == zfeature_lookup_guid(feature.fi_guid, NULL))
430 fatal("'%s' is a real feature, will not change refcount");
431
432 if (0 == zap_contains(mos, spa->spa_feat_for_read_obj,
433 feature.fi_guid)) {
434 feature.fi_can_readonly = B_FALSE;
435 } else if (0 == zap_contains(mos, spa->spa_feat_for_write_obj,
436 feature.fi_guid)) {
437 feature.fi_can_readonly = B_TRUE;
438 } else {
439 fatal("feature is not enabled: %s", feature.fi_guid);
440 }
441
442 if (decr && !spa_feature_is_active(spa, &feature))
443 fatal("feature refcount already 0: %s", feature.fi_guid);
444
445 VERIFY0(dsl_sync_task_do(spa->spa_dsl_pool, NULL,
446 decr ? feature_decr_sync : feature_incr_sync, spa, &feature, 5));
447
448 spa_close(spa, FTAG);
449 }
450
451 static int
452 zhack_do_feature(int argc, char **argv)
453 {
454 char *subcommand;
455
456 argc--;
457 argv++;
458 if (argc == 0) {
459 (void) fprintf(stderr,
460 "error: no feature operation specified\n");
461 usage();
462 }
463
464 subcommand = argv[0];
465 if (strcmp(subcommand, "stat") == 0) {
|