Print this page
1693 persistent 'comment' field for a zpool

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/zfs/spa.c
          +++ new/usr/src/uts/common/fs/zfs/spa.c
↓ open down ↓ 197 lines elided ↑ open up ↑
 198  198                  version = spa_version(spa);
 199  199                  if (version == zpool_prop_default_numeric(ZPOOL_PROP_VERSION))
 200  200                          src = ZPROP_SRC_DEFAULT;
 201  201                  else
 202  202                          src = ZPROP_SRC_LOCAL;
 203  203                  spa_prop_add_list(*nvp, ZPOOL_PROP_VERSION, NULL, version, src);
 204  204          }
 205  205  
 206  206          spa_prop_add_list(*nvp, ZPOOL_PROP_GUID, NULL, spa_guid(spa), src);
 207  207  
      208 +        if (spa->spa_comment != NULL) {
      209 +                spa_prop_add_list(*nvp, ZPOOL_PROP_COMMENT, spa->spa_comment,
      210 +                    0, ZPROP_SRC_LOCAL);
      211 +        }
      212 +
 208  213          if (spa->spa_root != NULL)
 209  214                  spa_prop_add_list(*nvp, ZPOOL_PROP_ALTROOT, spa->spa_root,
 210  215                      0, ZPROP_SRC_LOCAL);
 211  216  
 212  217          if ((dp = list_head(&spa->spa_config_list)) != NULL) {
 213  218                  if (dp->scd_path == NULL) {
 214  219                          spa_prop_add_list(*nvp, ZPOOL_PROP_CACHEFILE,
 215  220                              "none", 0, ZPROP_SRC_LOCAL);
 216  221                  } else if (strcmp(dp->scd_path, spa_config_path) != 0) {
 217  222                          spa_prop_add_list(*nvp, ZPOOL_PROP_CACHEFILE,
↓ open down ↓ 119 lines elided ↑ open up ↑
 337  342          nvpair_t *elem;
 338  343          int error = 0, reset_bootfs = 0;
 339  344          uint64_t objnum;
 340  345  
 341  346          elem = NULL;
 342  347          while ((elem = nvlist_next_nvpair(props, elem)) != NULL) {
 343  348                  zpool_prop_t prop;
 344  349                  char *propname, *strval;
 345  350                  uint64_t intval;
 346  351                  objset_t *os;
 347      -                char *slash;
      352 +                char *slash, *check;
 348  353  
 349  354                  propname = nvpair_name(elem);
 350  355  
 351  356                  if ((prop = zpool_name_to_prop(propname)) == ZPROP_INVAL)
 352  357                          return (EINVAL);
 353  358  
 354  359                  switch (prop) {
 355  360                  case ZPOOL_PROP_VERSION:
 356  361                          error = nvpair_value_uint64(elem, &intval);
 357  362                          if (!error &&
↓ open down ↓ 99 lines elided ↑ open up ↑
 457  462                          }
 458  463  
 459  464                          slash = strrchr(strval, '/');
 460  465                          ASSERT(slash != NULL);
 461  466  
 462  467                          if (slash[1] == '\0' || strcmp(slash, "/.") == 0 ||
 463  468                              strcmp(slash, "/..") == 0)
 464  469                                  error = EINVAL;
 465  470                          break;
 466  471  
      472 +                case ZPOOL_PROP_COMMENT:
      473 +                        if ((error = nvpair_value_string(elem, &strval)) != 0)
      474 +                                break;
      475 +                        for (check = strval; *check != '\0'; check++) {
      476 +                                /*
      477 +                                 * The kernel doesn't have an easy isprint()
      478 +                                 * check.  For this kernel check, we merely
      479 +                                 * check ASCII apart from DEL.  Fix this if
      480 +                                 * there is an easy-to-use kernel isprint().
      481 +                                 */
      482 +                                if (*check >= 0x7f) {
      483 +                                        error = EINVAL;
      484 +                                        break;
      485 +                                }
      486 +                                check++;
      487 +                        }
      488 +                        if (strlen(strval) > ZPROP_MAX_COMMENT)
      489 +                                error = E2BIG;
      490 +                        break;
      491 +
 467  492                  case ZPOOL_PROP_DEDUPDITTO:
 468  493                          if (spa_version(spa) < SPA_VERSION_DEDUP)
 469  494                                  error = ENOTSUP;
 470  495                          else
 471  496                                  error = nvpair_value_uint64(elem, &intval);
 472  497                          if (error == 0 &&
 473  498                              intval != 0 && intval < ZIO_DEDUPDITTO_MIN)
 474  499                                  error = EINVAL;
 475  500                          break;
 476  501                  }
↓ open down ↓ 558 lines elided ↑ open up ↑
1035 1060                  spa->spa_l2cache.sav_vdevs = NULL;
1036 1061          }
1037 1062          if (spa->spa_l2cache.sav_config) {
1038 1063                  nvlist_free(spa->spa_l2cache.sav_config);
1039 1064                  spa->spa_l2cache.sav_config = NULL;
1040 1065          }
1041 1066          spa->spa_l2cache.sav_count = 0;
1042 1067  
1043 1068          spa->spa_async_suspended = 0;
1044 1069  
     1070 +        if (spa->spa_comment != NULL) {
     1071 +                spa_strfree(spa->spa_comment);
     1072 +                spa->spa_comment = NULL;
     1073 +        }
     1074 +
1045 1075          spa_config_exit(spa, SCL_ALL, FTAG);
1046 1076  }
1047 1077  
1048 1078  /*
1049 1079   * Load (or re-load) the current list of vdevs describing the active spares for
1050 1080   * this pool.  When this is called, we have some form of basic information in
1051 1081   * 'spa_spares.sav_config'.  We parse this into vdevs, try to open them, and
1052 1082   * then re-generate a more complete list including status information.
1053 1083   */
1054 1084  static void
↓ open down ↓ 695 lines elided ↑ open up ↑
1750 1780  
1751 1781          kmem_free(vd, gcount * sizeof (vdev_t *));
1752 1782  }
1753 1783  
1754 1784  static int
1755 1785  spa_load(spa_t *spa, spa_load_state_t state, spa_import_type_t type,
1756 1786      boolean_t mosconfig)
1757 1787  {
1758 1788          nvlist_t *config = spa->spa_config;
1759 1789          char *ereport = FM_EREPORT_ZFS_POOL;
     1790 +        char *comment;
1760 1791          int error;
1761 1792          uint64_t pool_guid;
1762 1793          nvlist_t *nvl;
1763 1794  
1764 1795          if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, &pool_guid))
1765 1796                  return (EINVAL);
1766 1797  
     1798 +        ASSERT(spa->spa_comment == NULL);
     1799 +        if (nvlist_lookup_string(config, ZPOOL_CONFIG_COMMENT, &comment) == 0)
     1800 +                spa->spa_comment = spa_strdup(comment);
     1801 +
1767 1802          /*
1768 1803           * Versioning wasn't explicitly added to the label until later, so if
1769 1804           * it's not present treat it as the initial version.
1770 1805           */
1771 1806          if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
1772 1807              &spa->spa_ubsync.ub_version) != 0)
1773 1808                  spa->spa_ubsync.ub_version = SPA_VERSION_INITIAL;
1774 1809  
1775 1810          (void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_TXG,
1776 1811              &spa->spa_config_txg);
↓ open down ↓ 3587 lines elided ↑ open up ↑
5364 5399                          ASSERT(spa->spa_root != NULL);
5365 5400                          break;
5366 5401  
5367 5402                  case ZPOOL_PROP_READONLY:
5368 5403                  case ZPOOL_PROP_CACHEFILE:
5369 5404                          /*
5370 5405                           * 'readonly' and 'cachefile' are also non-persisitent
5371 5406                           * properties.
5372 5407                           */
5373 5408                          break;
     5409 +                case ZPOOL_PROP_COMMENT:
     5410 +                        VERIFY(nvpair_value_string(elem, &strval) == 0);
     5411 +                        if (spa->spa_comment != NULL)
     5412 +                                spa_strfree(spa->spa_comment);
     5413 +                        spa->spa_comment = spa_strdup(strval);
     5414 +                        /*
     5415 +                         * We need to dirty the configuration on all the vdevs
     5416 +                         * so that their labels get updated.  It's unnecessary
     5417 +                         * to do this for pool creation since the vdev's
     5418 +                         * configuratoin has already been dirtied.
     5419 +                         */
     5420 +                        if (tx->tx_txg != TXG_INITIAL)
     5421 +                                vdev_config_dirty(spa->spa_root_vdev);
     5422 +                        break;
5374 5423                  default:
5375 5424                          /*
5376 5425                           * Set pool property values in the poolprops mos object.
5377 5426                           */
5378 5427                          if (spa->spa_pool_props_object == 0) {
5379 5428                                  VERIFY((spa->spa_pool_props_object =
5380 5429                                      zap_create(mos, DMU_OT_POOL_PROPS,
5381 5430                                      DMU_OT_NONE, 0, tx)) > 0);
5382 5431  
5383 5432                                  VERIFY(zap_update(mos,
↓ open down ↓ 538 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX