Print this page




  70  * The -N(okill) option will suppress kills, so each child runs to completion.
  71  * This can be useful when you're trying to distinguish temporal incursions
  72  * from plain old race conditions.
  73  */
  74 
  75 #include <sys/zfs_context.h>
  76 #include <sys/spa.h>
  77 #include <sys/dmu.h>
  78 #include <sys/txg.h>
  79 #include <sys/zap.h>
  80 #include <sys/dmu_objset.h>
  81 #include <sys/poll.h>
  82 #include <sys/stat.h>
  83 #include <sys/time.h>
  84 #include <sys/wait.h>
  85 #include <sys/mman.h>
  86 #include <sys/resource.h>
  87 #include <sys/zio.h>
  88 #include <sys/zio_checksum.h>
  89 #include <sys/zio_compress.h>

  90 #include <sys/zil.h>
  91 #include <sys/vdev_impl.h>
  92 #include <sys/vdev_file.h>
  93 #include <sys/spa_impl.h>
  94 #include <sys/dsl_prop.h>
  95 #include <sys/refcount.h>
  96 #include <stdio.h>
  97 #include <stdio_ext.h>
  98 #include <stdlib.h>
  99 #include <unistd.h>
 100 #include <signal.h>
 101 #include <umem.h>
 102 #include <dlfcn.h>
 103 #include <ctype.h>
 104 #include <math.h>
 105 #include <sys/fs/zfs.h>
 106 
 107 static char cmdname[] = "ztest";
 108 static char *zopt_pool = cmdname;
 109 


 681 ztest_random_checksum(void)
 682 {
 683         uint8_t checksum;
 684 
 685         do {
 686                 checksum = ztest_random(ZIO_CHECKSUM_FUNCTIONS);
 687         } while (zio_checksum_table[checksum].ci_zbt);
 688 
 689         if (checksum == ZIO_CHECKSUM_OFF)
 690                 checksum = ZIO_CHECKSUM_ON;
 691 
 692         return (checksum);
 693 }
 694 
 695 static uint8_t
 696 ztest_random_compress(void)
 697 {
 698         return ((uint8_t)ztest_random(ZIO_COMPRESS_FUNCTIONS));
 699 }
 700 






 701 static int
 702 ztest_replay_create(objset_t *os, lr_create_t *lr, boolean_t byteswap)
 703 {
 704         dmu_tx_t *tx;
 705         int error;
 706 
 707         if (byteswap)
 708                 byteswap_uint64_array(lr, sizeof (*lr));
 709 
 710         tx = dmu_tx_create(os);
 711         dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT);
 712         error = dmu_tx_assign(tx, TXG_WAIT);
 713         if (error) {
 714                 dmu_tx_abort(tx);
 715                 return (error);
 716         }
 717 
 718         error = dmu_object_claim(os, lr->lr_doid, lr->lr_mode, 0,
 719             DMU_OT_NONE, 0, tx);
 720         ASSERT3U(error, ==, 0);


1530                 dmu_tx_hold_write(tx, batchobj,
1531                     b * sizeof (uint64_t), sizeof (uint64_t));
1532                 dmu_tx_hold_free(tx, object, 0, DMU_OBJECT_END);
1533                 error = dmu_tx_assign(tx, TXG_WAIT);
1534                 if (error) {
1535                         ztest_record_enospc("free object");
1536                         dmu_tx_abort(tx);
1537                         return;
1538                 }
1539                 error = dmu_object_free(os, object, tx);
1540                 if (error) {
1541                         fatal(0, "dmu_object_free('%s', %llu) = %d",
1542                             osname, object, error);
1543                 }
1544                 object = 0;
1545 
1546                 dmu_object_set_checksum(os, batchobj,
1547                     ztest_random_checksum(), tx);
1548                 dmu_object_set_compress(os, batchobj,
1549                     ztest_random_compress(), tx);


1550 
1551                 dmu_write(os, batchobj, b * sizeof (uint64_t),
1552                     sizeof (uint64_t), &object, tx);
1553 
1554                 dmu_tx_commit(tx);
1555         }
1556 
1557         /*
1558          * Before creating the new batch of objects, generate a bunch of churn.
1559          */
1560         for (b = ztest_random(100); b > 0; b--) {
1561                 tx = dmu_tx_create(os);
1562                 dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT);
1563                 error = dmu_tx_assign(tx, TXG_WAIT);
1564                 if (error) {
1565                         ztest_record_enospc("churn objects");
1566                         dmu_tx_abort(tx);
1567                         return;
1568                 }
1569                 object = dmu_object_alloc(os, DMU_OT_UINT64_OTHER, 0,


1591                 dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT);
1592                 dmu_tx_hold_write(tx, DMU_NEW_OBJECT, endoff,
1593                     sizeof (uint64_t));
1594                 error = dmu_tx_assign(tx, TXG_WAIT);
1595                 if (error) {
1596                         ztest_record_enospc("create batchobj");
1597                         dmu_tx_abort(tx);
1598                         return;
1599                 }
1600                 bonuslen = (int)ztest_random(dmu_bonus_max()) + 1;
1601 
1602                 object = dmu_object_alloc(os, DMU_OT_UINT64_OTHER, 0,
1603                     DMU_OT_PLAIN_OTHER, bonuslen, tx);
1604 
1605                 ztest_set_random_blocksize(os, object, tx);
1606 
1607                 dmu_object_set_checksum(os, object,
1608                     ztest_random_checksum(), tx);
1609                 dmu_object_set_compress(os, object,
1610                     ztest_random_compress(), tx);


1611 
1612                 dmu_write(os, batchobj, b * sizeof (uint64_t),
1613                     sizeof (uint64_t), &object, tx);
1614 
1615                 /*
1616                  * Write to both the bonus buffer and the regular data.
1617                  */
1618                 VERIFY(dmu_bonus_hold(os, object, FTAG, &db) == 0);
1619                 za->za_dbuf = db;
1620                 ASSERT3U(bonuslen, <=, db->db_size);
1621 
1622                 dmu_object_size_from_db(db, &va_blksize, &va_nblocks);
1623                 ASSERT3S(va_nblocks, >=, 0);
1624 
1625                 dmu_buf_will_dirty(db, tx);
1626 
1627                 /*
1628                  * See comments above regarding the contents of
1629                  * the bonus buffer and the word at endoff.
1630                  */


2431 
2432         if (tx != NULL)
2433                 dmu_tx_commit(tx);
2434 }
2435 
2436 void
2437 ztest_dsl_prop_get_set(ztest_args_t *za)
2438 {
2439         objset_t *os = za->za_os;
2440         int i, inherit;
2441         uint64_t value;
2442         const char *prop, *valname;
2443         char setpoint[MAXPATHLEN];
2444         char osname[MAXNAMELEN];
2445         int error;
2446 
2447         (void) rw_rdlock(&ztest_shared->zs_name_lock);
2448 
2449         dmu_objset_name(os, osname);
2450 
2451         for (i = 0; i < 2; i++) {
2452                 if (i == 0) {
2453                         prop = "checksum";
2454                         value = ztest_random_checksum();
2455                         inherit = (value == ZIO_CHECKSUM_INHERIT);
2456                 } else {
2457                         prop = "compression";
2458                         value = ztest_random_compress();
2459                         inherit = (value == ZIO_COMPRESS_INHERIT);




2460                 }
2461 
2462                 error = dsl_prop_set(osname, prop, sizeof (value),
2463                     !inherit, &value);
2464 
2465                 if (error == ENOSPC) {
2466                         ztest_record_enospc("dsl_prop_set");
2467                         break;
2468                 }
2469 
2470                 ASSERT3U(error, ==, 0);
2471 
2472                 VERIFY3U(dsl_prop_get(osname, prop, sizeof (value),
2473                     1, &value, setpoint), ==, 0);
2474 
2475                 if (i == 0)
2476                         valname = zio_checksum_table[value].ci_name;
2477                 else
2478                         valname = zio_compress_table[value].ci_name;



2479 

2480                 if (zopt_verbose >= 6) {
2481                         (void) printf("%s %s = %s for '%s'\n",
2482                             osname, prop, valname, setpoint);
2483                 }
2484         }
2485 
2486         (void) rw_unlock(&ztest_shared->zs_name_lock);
2487 }
2488 
2489 /*
2490  * Inject random faults into the on-disk data.
2491  */
2492 void
2493 ztest_fault_inject(ztest_args_t *za)
2494 {
2495         int fd;
2496         uint64_t offset;
2497         uint64_t leaves = MAX(zopt_mirrors, 1) * zopt_raidz;
2498         uint64_t bad = 0x1990c0ffeedecade;
2499         uint64_t top, leaf;




  70  * The -N(okill) option will suppress kills, so each child runs to completion.
  71  * This can be useful when you're trying to distinguish temporal incursions
  72  * from plain old race conditions.
  73  */
  74 
  75 #include <sys/zfs_context.h>
  76 #include <sys/spa.h>
  77 #include <sys/dmu.h>
  78 #include <sys/txg.h>
  79 #include <sys/zap.h>
  80 #include <sys/dmu_objset.h>
  81 #include <sys/poll.h>
  82 #include <sys/stat.h>
  83 #include <sys/time.h>
  84 #include <sys/wait.h>
  85 #include <sys/mman.h>
  86 #include <sys/resource.h>
  87 #include <sys/zio.h>
  88 #include <sys/zio_checksum.h>
  89 #include <sys/zio_compress.h>
  90 #include <sys/zio_crypt.h>
  91 #include <sys/zil.h>
  92 #include <sys/vdev_impl.h>
  93 #include <sys/vdev_file.h>
  94 #include <sys/spa_impl.h>
  95 #include <sys/dsl_prop.h>
  96 #include <sys/refcount.h>
  97 #include <stdio.h>
  98 #include <stdio_ext.h>
  99 #include <stdlib.h>
 100 #include <unistd.h>
 101 #include <signal.h>
 102 #include <umem.h>
 103 #include <dlfcn.h>
 104 #include <ctype.h>
 105 #include <math.h>
 106 #include <sys/fs/zfs.h>
 107 
 108 static char cmdname[] = "ztest";
 109 static char *zopt_pool = cmdname;
 110 


 682 ztest_random_checksum(void)
 683 {
 684         uint8_t checksum;
 685 
 686         do {
 687                 checksum = ztest_random(ZIO_CHECKSUM_FUNCTIONS);
 688         } while (zio_checksum_table[checksum].ci_zbt);
 689 
 690         if (checksum == ZIO_CHECKSUM_OFF)
 691                 checksum = ZIO_CHECKSUM_ON;
 692 
 693         return (checksum);
 694 }
 695 
 696 static uint8_t
 697 ztest_random_compress(void)
 698 {
 699         return ((uint8_t)ztest_random(ZIO_COMPRESS_FUNCTIONS));
 700 }
 701 
 702 static uint8_t
 703 ztest_random_crypt(void)
 704 {
 705         return ((uint8_t)ztest_random(ZIO_CRYPT_FUNCTIONS));
 706 }
 707 
 708 static int
 709 ztest_replay_create(objset_t *os, lr_create_t *lr, boolean_t byteswap)
 710 {
 711         dmu_tx_t *tx;
 712         int error;
 713 
 714         if (byteswap)
 715                 byteswap_uint64_array(lr, sizeof (*lr));
 716 
 717         tx = dmu_tx_create(os);
 718         dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT);
 719         error = dmu_tx_assign(tx, TXG_WAIT);
 720         if (error) {
 721                 dmu_tx_abort(tx);
 722                 return (error);
 723         }
 724 
 725         error = dmu_object_claim(os, lr->lr_doid, lr->lr_mode, 0,
 726             DMU_OT_NONE, 0, tx);
 727         ASSERT3U(error, ==, 0);


1537                 dmu_tx_hold_write(tx, batchobj,
1538                     b * sizeof (uint64_t), sizeof (uint64_t));
1539                 dmu_tx_hold_free(tx, object, 0, DMU_OBJECT_END);
1540                 error = dmu_tx_assign(tx, TXG_WAIT);
1541                 if (error) {
1542                         ztest_record_enospc("free object");
1543                         dmu_tx_abort(tx);
1544                         return;
1545                 }
1546                 error = dmu_object_free(os, object, tx);
1547                 if (error) {
1548                         fatal(0, "dmu_object_free('%s', %llu) = %d",
1549                             osname, object, error);
1550                 }
1551                 object = 0;
1552 
1553                 dmu_object_set_checksum(os, batchobj,
1554                     ztest_random_checksum(), tx);
1555                 dmu_object_set_compress(os, batchobj,
1556                     ztest_random_compress(), tx);
1557                 dmu_object_set_crypt(os, batchobj,
1558                     ztest_random_crypt(), tx);
1559 
1560                 dmu_write(os, batchobj, b * sizeof (uint64_t),
1561                     sizeof (uint64_t), &object, tx);
1562 
1563                 dmu_tx_commit(tx);
1564         }
1565 
1566         /*
1567          * Before creating the new batch of objects, generate a bunch of churn.
1568          */
1569         for (b = ztest_random(100); b > 0; b--) {
1570                 tx = dmu_tx_create(os);
1571                 dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT);
1572                 error = dmu_tx_assign(tx, TXG_WAIT);
1573                 if (error) {
1574                         ztest_record_enospc("churn objects");
1575                         dmu_tx_abort(tx);
1576                         return;
1577                 }
1578                 object = dmu_object_alloc(os, DMU_OT_UINT64_OTHER, 0,


1600                 dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT);
1601                 dmu_tx_hold_write(tx, DMU_NEW_OBJECT, endoff,
1602                     sizeof (uint64_t));
1603                 error = dmu_tx_assign(tx, TXG_WAIT);
1604                 if (error) {
1605                         ztest_record_enospc("create batchobj");
1606                         dmu_tx_abort(tx);
1607                         return;
1608                 }
1609                 bonuslen = (int)ztest_random(dmu_bonus_max()) + 1;
1610 
1611                 object = dmu_object_alloc(os, DMU_OT_UINT64_OTHER, 0,
1612                     DMU_OT_PLAIN_OTHER, bonuslen, tx);
1613 
1614                 ztest_set_random_blocksize(os, object, tx);
1615 
1616                 dmu_object_set_checksum(os, object,
1617                     ztest_random_checksum(), tx);
1618                 dmu_object_set_compress(os, object,
1619                     ztest_random_compress(), tx);
1620                 dmu_object_set_crypt(os, object,
1621                     ztest_random_crypt(), tx);
1622 
1623                 dmu_write(os, batchobj, b * sizeof (uint64_t),
1624                     sizeof (uint64_t), &object, tx);
1625 
1626                 /*
1627                  * Write to both the bonus buffer and the regular data.
1628                  */
1629                 VERIFY(dmu_bonus_hold(os, object, FTAG, &db) == 0);
1630                 za->za_dbuf = db;
1631                 ASSERT3U(bonuslen, <=, db->db_size);
1632 
1633                 dmu_object_size_from_db(db, &va_blksize, &va_nblocks);
1634                 ASSERT3S(va_nblocks, >=, 0);
1635 
1636                 dmu_buf_will_dirty(db, tx);
1637 
1638                 /*
1639                  * See comments above regarding the contents of
1640                  * the bonus buffer and the word at endoff.
1641                  */


2442 
2443         if (tx != NULL)
2444                 dmu_tx_commit(tx);
2445 }
2446 
2447 void
2448 ztest_dsl_prop_get_set(ztest_args_t *za)
2449 {
2450         objset_t *os = za->za_os;
2451         int i, inherit;
2452         uint64_t value;
2453         const char *prop, *valname;
2454         char setpoint[MAXPATHLEN];
2455         char osname[MAXNAMELEN];
2456         int error;
2457 
2458         (void) rw_rdlock(&ztest_shared->zs_name_lock);
2459 
2460         dmu_objset_name(os, osname);
2461 
2462         for (i = 0; i < 3; i++) {
2463                 if (i == 0) {
2464                         prop = "checksum";
2465                         value = ztest_random_checksum();
2466                         inherit = (value == ZIO_CHECKSUM_INHERIT);
2467                 } else if (i == 1) {
2468                         prop = "compression";
2469                         value = ztest_random_compress();
2470                         inherit = (value == ZIO_COMPRESS_INHERIT);
2471                 } else {
2472                         prop = "crypt";
2473                         value = ztest_random_crypt();
2474                         inherit = (value == ZIO_CRYPT_INHERIT);
2475                 }
2476 
2477                 error = dsl_prop_set(osname, prop, sizeof (value),
2478                     !inherit, &value);
2479 
2480                 if (error == ENOSPC) {
2481                         ztest_record_enospc("dsl_prop_set");
2482                         break;
2483                 }
2484 
2485                 ASSERT3U(error, ==, 0);
2486 
2487                 VERIFY3U(dsl_prop_get(osname, prop, sizeof (value),
2488                     1, &value, setpoint), ==, 0);
2489 
2490                 if (i == 0) {
2491                         valname = zio_checksum_table[value].ci_name;
2492                 } else if (i == 1) {
2493                         valname = zio_compress_table[value].ci_name;
2494                 } else {
2495                         valname = zio_crypt_table[value].ci_name;
2496                 }
2497 
2498 
2499                 if (zopt_verbose >= 6) {
2500                         (void) printf("%s %s = %s for '%s'\n",
2501                             osname, prop, valname, setpoint);
2502                 }
2503         }
2504 
2505         (void) rw_unlock(&ztest_shared->zs_name_lock);
2506 }
2507 
2508 /*
2509  * Inject random faults into the on-disk data.
2510  */
2511 void
2512 ztest_fault_inject(ztest_args_t *za)
2513 {
2514         int fd;
2515         uint64_t offset;
2516         uint64_t leaves = MAX(zopt_mirrors, 1) * zopt_raidz;
2517         uint64_t bad = 0x1990c0ffeedecade;
2518         uint64_t top, leaf;