262 target = argv[0];
263
264 zhack_spa_open(target, B_TRUE, FTAG, &spa);
265 os = spa->spa_meta_objset;
266
267 dump_obj(os, spa->spa_feat_for_read_obj, "for_read");
268 dump_obj(os, spa->spa_feat_for_write_obj, "for_write");
269 dump_obj(os, spa->spa_feat_desc_obj, "descriptions");
270 dump_mos(spa);
271
272 spa_close(spa, FTAG);
273 }
274
275 static void
276 feature_enable_sync(void *arg1, void *arg2, dmu_tx_t *tx)
277 {
278 spa_t *spa = arg1;
279 zfeature_info_t *feature = arg2;
280
281 spa_feature_enable(spa, feature, tx);
282 }
283
284 static void
285 zhack_do_feature_enable(int argc, char **argv)
286 {
287 char c;
288 char *desc, *target;
289 spa_t *spa;
290 objset_t *mos;
291 zfeature_info_t feature;
292 zfeature_info_t *nodeps[] = { NULL };
293
294 /*
295 * Features are not added to the pool's label until their refcounts
296 * are incremented, so fi_mos can just be left as false for now.
297 */
298 desc = NULL;
299 feature.fi_uname = "zhack";
300 feature.fi_mos = B_FALSE;
301 feature.fi_can_readonly = B_FALSE;
339 if (0 == zfeature_lookup_guid(feature.fi_guid, NULL))
340 fatal("'%s' is a real feature, will not enable");
341 if (0 == zap_contains(mos, spa->spa_feat_desc_obj, feature.fi_guid))
342 fatal("feature already enabled: %s", feature.fi_guid);
343
344 VERIFY3U(0, ==, dsl_sync_task_do(spa->spa_dsl_pool, NULL,
345 feature_enable_sync, spa, &feature, 5));
346
347 spa_close(spa, FTAG);
348
349 free(desc);
350 }
351
352 static void
353 feature_incr_sync(void *arg1, void *arg2, dmu_tx_t *tx)
354 {
355 spa_t *spa = arg1;
356 zfeature_info_t *feature = arg2;
357
358 spa_feature_incr(spa, feature, tx);
359 }
360
361 static void
362 feature_decr_sync(void *arg1, void *arg2, dmu_tx_t *tx)
363 {
364 spa_t *spa = arg1;
365 zfeature_info_t *feature = arg2;
366
367 spa_feature_decr(spa, feature, tx);
368 }
369
370 static void
371 zhack_do_feature_ref(int argc, char **argv)
372 {
373 char c;
374 char *target;
375 boolean_t decr = B_FALSE;
376 spa_t *spa;
377 objset_t *mos;
378 zfeature_info_t feature;
379 zfeature_info_t *nodeps[] = { NULL };
380
381 /*
382 * fi_desc does not matter here because it was written to disk
383 * when the feature was enabled, but we need to properly set the
384 * feature for read or write based on the information we read off
385 * disk later.
386 */
387 feature.fi_uname = "zhack";
|
262 target = argv[0];
263
264 zhack_spa_open(target, B_TRUE, FTAG, &spa);
265 os = spa->spa_meta_objset;
266
267 dump_obj(os, spa->spa_feat_for_read_obj, "for_read");
268 dump_obj(os, spa->spa_feat_for_write_obj, "for_write");
269 dump_obj(os, spa->spa_feat_desc_obj, "descriptions");
270 dump_mos(spa);
271
272 spa_close(spa, FTAG);
273 }
274
275 static void
276 feature_enable_sync(void *arg1, void *arg2, dmu_tx_t *tx)
277 {
278 spa_t *spa = arg1;
279 zfeature_info_t *feature = arg2;
280
281 spa_feature_enable(spa, feature, tx);
282 spa_history_log_internal(spa, "zhack enable feature", tx,
283 "name=%s can_readonly=%u",
284 feature->fi_guid, feature->fi_can_readonly);
285 }
286
287 static void
288 zhack_do_feature_enable(int argc, char **argv)
289 {
290 char c;
291 char *desc, *target;
292 spa_t *spa;
293 objset_t *mos;
294 zfeature_info_t feature;
295 zfeature_info_t *nodeps[] = { NULL };
296
297 /*
298 * Features are not added to the pool's label until their refcounts
299 * are incremented, so fi_mos can just be left as false for now.
300 */
301 desc = NULL;
302 feature.fi_uname = "zhack";
303 feature.fi_mos = B_FALSE;
304 feature.fi_can_readonly = B_FALSE;
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)
368 {
369 spa_t *spa = arg1;
370 zfeature_info_t *feature = arg2;
371
372 spa_feature_decr(spa, feature, tx);
373 spa_history_log_internal(spa, "zhack feature decr", tx,
374 "name=%s", feature->fi_guid);
375 }
376
377 static void
378 zhack_do_feature_ref(int argc, char **argv)
379 {
380 char c;
381 char *target;
382 boolean_t decr = B_FALSE;
383 spa_t *spa;
384 objset_t *mos;
385 zfeature_info_t feature;
386 zfeature_info_t *nodeps[] = { NULL };
387
388 /*
389 * fi_desc does not matter here because it was written to disk
390 * when the feature was enabled, but we need to properly set the
391 * feature for read or write based on the information we read off
392 * disk later.
393 */
394 feature.fi_uname = "zhack";
|