Print this page
1693 persistent 'comment' field for a zpool
        
*** 203,212 ****
--- 203,217 ----
                  spa_prop_add_list(*nvp, ZPOOL_PROP_VERSION, NULL, version, src);
          }
  
          spa_prop_add_list(*nvp, ZPOOL_PROP_GUID, NULL, spa_guid(spa), src);
  
+         if (spa->spa_comment != NULL) {
+                 spa_prop_add_list(*nvp, ZPOOL_PROP_COMMENT, spa->spa_comment,
+                     0, ZPROP_SRC_LOCAL);
+         }
+ 
          if (spa->spa_root != NULL)
                  spa_prop_add_list(*nvp, ZPOOL_PROP_ALTROOT, spa->spa_root,
                      0, ZPROP_SRC_LOCAL);
  
          if ((dp = list_head(&spa->spa_config_list)) != NULL) {
*** 342,352 ****
          while ((elem = nvlist_next_nvpair(props, elem)) != NULL) {
                  zpool_prop_t prop;
                  char *propname, *strval;
                  uint64_t intval;
                  objset_t *os;
!                 char *slash;
  
                  propname = nvpair_name(elem);
  
                  if ((prop = zpool_name_to_prop(propname)) == ZPROP_INVAL)
                          return (EINVAL);
--- 347,357 ----
          while ((elem = nvlist_next_nvpair(props, elem)) != NULL) {
                  zpool_prop_t prop;
                  char *propname, *strval;
                  uint64_t intval;
                  objset_t *os;
!                 char *slash, *check;
  
                  propname = nvpair_name(elem);
  
                  if ((prop = zpool_name_to_prop(propname)) == ZPROP_INVAL)
                          return (EINVAL);
*** 462,471 ****
--- 467,496 ----
                          if (slash[1] == '\0' || strcmp(slash, "/.") == 0 ||
                              strcmp(slash, "/..") == 0)
                                  error = EINVAL;
                          break;
  
+                 case ZPOOL_PROP_COMMENT:
+                         if ((error = nvpair_value_string(elem, &strval)) != 0)
+                                 break;
+                         for (check = strval; *check != '\0'; check++) {
+                                 /*
+                                  * The kernel doesn't have an easy isprint()
+                                  * check.  For this kernel check, we merely
+                                  * check ASCII apart from DEL.  Fix this if
+                                  * there is an easy-to-use kernel isprint().
+                                  */
+                                 if (*check >= 0x7f) {
+                                         error = EINVAL;
+                                         break;
+                                 }
+                                 check++;
+                         }
+                         if (strlen(strval) > ZPROP_MAX_COMMENT)
+                                 error = E2BIG;
+                         break;
+ 
                  case ZPOOL_PROP_DEDUPDITTO:
                          if (spa_version(spa) < SPA_VERSION_DEDUP)
                                  error = ENOTSUP;
                          else
                                  error = nvpair_value_uint64(elem, &intval);
*** 1040,1049 ****
--- 1065,1079 ----
          }
          spa->spa_l2cache.sav_count = 0;
  
          spa->spa_async_suspended = 0;
  
+         if (spa->spa_comment != NULL) {
+                 spa_strfree(spa->spa_comment);
+                 spa->spa_comment = NULL;
+         }
+ 
          spa_config_exit(spa, SCL_ALL, FTAG);
  }
  
  /*
   * Load (or re-load) the current list of vdevs describing the active spares for
*** 1755,1771 ****
--- 1785,1806 ----
  spa_load(spa_t *spa, spa_load_state_t state, spa_import_type_t type,
      boolean_t mosconfig)
  {
          nvlist_t *config = spa->spa_config;
          char *ereport = FM_EREPORT_ZFS_POOL;
+         char *comment;
          int error;
          uint64_t pool_guid;
          nvlist_t *nvl;
  
          if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, &pool_guid))
                  return (EINVAL);
  
+         ASSERT(spa->spa_comment == NULL);
+         if (nvlist_lookup_string(config, ZPOOL_CONFIG_COMMENT, &comment) == 0)
+                 spa->spa_comment = spa_strdup(comment);
+ 
          /*
           * Versioning wasn't explicitly added to the label until later, so if
           * it's not present treat it as the initial version.
           */
          if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
*** 5369,5378 ****
--- 5404,5427 ----
                          /*
                           * 'readonly' and 'cachefile' are also non-persisitent
                           * properties.
                           */
                          break;
+                 case ZPOOL_PROP_COMMENT:
+                         VERIFY(nvpair_value_string(elem, &strval) == 0);
+                         if (spa->spa_comment != NULL)
+                                 spa_strfree(spa->spa_comment);
+                         spa->spa_comment = spa_strdup(strval);
+                         /*
+                          * We need to dirty the configuration on all the vdevs
+                          * so that their labels get updated.  It's unnecessary
+                          * to do this for pool creation since the vdev's
+                          * configuratoin has already been dirtied.
+                          */
+                         if (tx->tx_txg != TXG_INITIAL)
+                                 vdev_config_dirty(spa->spa_root_vdev);
+                         break;
                  default:
                          /*
                           * Set pool property values in the poolprops mos object.
                           */
                          if (spa->spa_pool_props_object == 0) {