Skip to content
This repository has been archived by the owner on Feb 16, 2020. It is now read-only.

Commit

Permalink
Imported code changes to support ashift=xxx.
Browse files Browse the repository at this point in the history
This imports the code chages needed to support the ashift property
in maczfs_74 from branch "ashift12".
  • Loading branch information
BjoKaSH committed Aug 24, 2012
1 parent 93b251f commit f38897e
Show file tree
Hide file tree
Showing 11 changed files with 227 additions and 26 deletions.
80 changes: 73 additions & 7 deletions usr/src/cmd/zpool/zpool_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,8 @@ get_usage(zpool_help_t idx) {
case HELP_CLEAR:
return (gettext("\tclear <pool> [device]\n"));
case HELP_CREATE:
return (gettext("\tcreate [-fn] [-R root] [-m mountpoint] "
"<pool> <vdev> ...\n"));
return (gettext("\tcreate [-fn] [-o property=value] ... \n"
"\t [-m mountpoint] [-R root] <pool> <vdev> ...\n"));
case HELP_DESTROY:
return (gettext("\tdestroy [-f] <pool>\n"));
case HELP_DETACH:
Expand Down Expand Up @@ -445,6 +445,52 @@ print_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent,
}
}

/*
* Add a property pair (name, string-value) into a property nvlist.
*/
static int
add_prop_list(const char *propname, char *propval, nvlist_t **props,
boolean_t poolprop)
{
zpool_prop_t prop = ZPOOL_PROP_INVAL;
zfs_prop_t fprop;
nvlist_t *proplist;
const char *normnm;
char *strval;

if (*props == NULL &&
nvlist_alloc(props, NV_UNIQUE_NAME, 0) != 0) {
(void) fprintf(stderr,
gettext("internal error: out of memory\n"));
return (1);
}

proplist = *props;

if (poolprop) {
if ((prop = zpool_name_to_prop(propname)) == ZPOOL_PROP_INVAL) {
(void) fprintf(stderr, gettext("property '%s' is "
"not a valid pool property\n"), propname);
return (2);
}
normnm = zpool_prop_to_name(prop);
} else {
if ((fprop = zfs_name_to_prop(propname)) != ZFS_PROP_INVAL) {
normnm = zfs_prop_to_name(fprop);
} else {
normnm = propname;
}
}

if (nvlist_add_string(proplist, normnm, propval) != 0) {
(void) fprintf(stderr, gettext("internal "
"error: out of memory\n"));
return (1);
}

return (0);
}

/*
* zpool add [-fn] <pool> <vdev> ...
*
Expand Down Expand Up @@ -513,7 +559,7 @@ zpool_do_add(int argc, char **argv)
}

/* pass off to get_vdev_spec for processing */
nvroot = make_root_vdev(zhp, force, !force, B_FALSE, argc, argv);
nvroot = make_root_vdev(zhp, NULL, force, !force, B_FALSE, argc, argv);
if (nvroot == NULL) {
zpool_close(zhp);
return (1);
Expand Down Expand Up @@ -589,14 +635,15 @@ zpool_do_remove(int argc, char **argv)
}

/*
* zpool create [-fn] [-R root] [-m mountpoint] <pool> <dev> ...
* zpool create [-fn] [-o property=value] ... [-R root] [-m mountpoint] <pool> <dev> ...
*
* -f Force creation, even if devices appear in use
* -n Do not create the pool, but display the resulting layout if it
* were to be created.
* -R Create a pool under an alternate root
* -m Set default mountpoint for the root dataset. By default it's
* '/<pool>'
* -o Set property=value.
*
* Creates the named pool according to the given vdev specification. The
* bulk of the vdev processing is done in get_vdev_spec() in zpool_vdev.c. Once
Expand All @@ -616,9 +663,11 @@ zpool_do_create(int argc, char **argv)
char *mountpoint = NULL;
nvlist_t **child;
uint_t children;
nvlist_t *props = NULL;
char *propval = NULL;

/* check options */
while ((c = getopt(argc, argv, ":fnR:m:")) != -1) {
while ((c = getopt(argc, argv, ":fnR:m:o:")) != -1) {
switch (c) {
case 'f':
force = B_TRUE;
Expand All @@ -632,6 +681,17 @@ zpool_do_create(int argc, char **argv)
case 'm':
mountpoint = optarg;
break;
case 'o':
if ((propval = strchr(optarg, '=')) == NULL) {
(void) fprintf(stderr, gettext("missing "
"'=' for -o option\n"));
usage(B_FALSE);
}
*propval = '\0';
propval++;
if (add_prop_list(optarg, propval, &props, B_TRUE))
usage(B_FALSE);
break;
case ':':
(void) fprintf(stderr, gettext("missing argument for "
"'%c' option\n"), optopt);
Expand Down Expand Up @@ -672,7 +732,7 @@ zpool_do_create(int argc, char **argv)
}

/* pass off to get_vdev_spec for bulk processing */
nvroot = make_root_vdev(NULL, force, !force, B_FALSE, argc - 1,
nvroot = make_root_vdev(NULL, props, force, !force, B_FALSE, argc - 1,
argv + 1);
if (nvroot == NULL)
return (1);
Expand Down Expand Up @@ -766,6 +826,12 @@ zpool_do_create(int argc, char **argv)
ret = 0;
} else {
ret = 1;
/*
* Add other properties not describing the vdev topology
*/
if (props)
nvlist_add_nvlist(nvroot, ZPOOL_CONFIG_PROPS, props);

/*
* Hand off to libzfs.
*/
Expand Down Expand Up @@ -2322,7 +2388,7 @@ zpool_do_attach_or_replace(int argc, char **argv, int replacing)
return (1);
}

nvroot = make_root_vdev(zhp, force, B_FALSE, replacing, argc, argv);
nvroot = make_root_vdev(zhp, NULL, force, B_FALSE, replacing, argc, argv);
if (nvroot == NULL) {
zpool_close(zhp);
return (1);
Expand Down
2 changes: 1 addition & 1 deletion usr/src/cmd/zpool/zpool_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ uint_t num_logs(nvlist_t *nv);
* Virtual device functions
*/

nvlist_t *make_root_vdev(zpool_handle_t *zhp, int force, int check_rep,
nvlist_t *make_root_vdev(zpool_handle_t *zhp, nvlist_t *props, int force, int check_rep,
boolean_t isreplace, int argc, char **argv);

/*
Expand Down
26 changes: 20 additions & 6 deletions usr/src/cmd/zpool/zpool_vdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ is_whole_disk(const char *arg)
* xxx Shorthand for /dev/dsk/xxx
*/
static nvlist_t *
make_leaf_vdev(const char *arg, uint64_t is_log)
make_leaf_vdev(nvlist_t *props, const char *arg, uint64_t is_log)
{
char path[MAXPATHLEN];
struct stat statbuf;
Expand Down Expand Up @@ -538,6 +538,20 @@ make_leaf_vdev(const char *arg, uint64_t is_log)
(void) close(fd);
}

if (props != NULL) {

uint64_t ashift = 0;
char *value = NULL;

if (nvlist_lookup_string(props,
zpool_prop_to_name(ZPOOL_PROP_ASHIFT), &value) == 0)
zfs_nicestrtonum(NULL, value, &ashift);

if (ashift > 0)
verify(nvlist_add_uint64(vdev, ZPOOL_CONFIG_ASHIFT,
ashift) == 0);
}

return (vdev);
}

Expand Down Expand Up @@ -1158,7 +1172,7 @@ is_grouping(const char *type, int *mindev)
* because the program is just going to exit anyway.
*/
nvlist_t *
construct_spec(int argc, char **argv)
construct_spec(nvlist_t *props, int argc, char **argv)
{
nvlist_t *nvroot, *nv, **top, **spares;
int t, toplevels, mindev, nspares, nlogs;
Expand Down Expand Up @@ -1234,7 +1248,7 @@ construct_spec(int argc, char **argv)
children * sizeof (nvlist_t *));
if (child == NULL)
zpool_no_memory();
if ((nv = make_leaf_vdev(argv[c], B_FALSE))
if ((nv = make_leaf_vdev(props, argv[c], B_FALSE))
== NULL)
return (NULL);
child[children - 1] = nv;
Expand Down Expand Up @@ -1279,7 +1293,7 @@ construct_spec(int argc, char **argv)
* We have a device. Pass off to make_leaf_vdev() to
* construct the appropriate nvlist describing the vdev.
*/
if ((nv = make_leaf_vdev(argv[0], is_log)) == NULL)
if ((nv = make_leaf_vdev(props, argv[0], is_log)) == NULL)
return (NULL);
if (is_log)
nlogs++;
Expand Down Expand Up @@ -1342,7 +1356,7 @@ construct_spec(int argc, char **argv)
* added, even if they appear in use.
*/
nvlist_t *
make_root_vdev(zpool_handle_t *zhp, int force, int check_rep,
make_root_vdev(zpool_handle_t *zhp, nvlist_t *props, int force, int check_rep,
boolean_t isreplacing, int argc, char **argv)
{
nvlist_t *newroot;
Expand All @@ -1354,7 +1368,7 @@ make_root_vdev(zpool_handle_t *zhp, int force, int check_rep,
* that we have a valid specification, and that all devices can be
* opened.
*/
if ((newroot = construct_spec(argc, argv)) == NULL)
if ((newroot = construct_spec(props, argc, argv)) == NULL)
return (NULL);

if (zhp && ((poolconfig = zpool_get_config(zhp, NULL)) == NULL))
Expand Down
31 changes: 27 additions & 4 deletions usr/src/common/zfs/zfs_prop.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,14 @@
typedef enum {
PROP_DEFAULT,
PROP_READONLY,
PROP_INHERIT
PROP_INHERIT,
/*
* ONETIME properties are a sort of conglomeration of READONLY
* and INHERIT. They can be set only during object creation,
* after that they are READONLY. If not explicitly set during
* creation, they can be inherited.
*/
PROP_ONETIME
} prop_attr_t;

typedef struct zfs_index {
Expand Down Expand Up @@ -326,10 +333,15 @@ zfs_prop_init(void)
register_number(ZFS_PROP_COMPRESSRATIO, "compressratio", 0,
PROP_READONLY, ZFS_TYPE_ANY,
"<1.00x or higher if compressed>", "RATIO");

/* readonly onetime number properties */
register_number(ZPOOL_PROP_ASHIFT, "ashift", 0, PROP_ONETIME,
ZFS_TYPE_POOL, "<ashift, 9-17, or 0=default>", "ASHIFT");
register_number(ZFS_PROP_VOLBLOCKSIZE, "volblocksize", 8192,
PROP_READONLY,
PROP_ONETIME,
ZFS_TYPE_VOLUME, "512 to 128k, power of 2", "VOLBLOCK");


/* default number properties */
register_number(ZFS_PROP_QUOTA, "quota", 0, PROP_DEFAULT,
ZFS_TYPE_FILESYSTEM, "<size> | none", "QUOTA");
Expand Down Expand Up @@ -616,7 +628,17 @@ zpool_prop_default_numeric(zpool_prop_t prop)
int
zfs_prop_readonly(zfs_prop_t prop)
{
return (zfs_prop_table[prop].pd_attr == PROP_READONLY);
return (zfs_prop_table[prop].pd_attr == PROP_READONLY ||
zfs_prop_table[prop].pd_attr == PROP_ONETIME);
}

/*
* Returns TRUE if the property is only allowed to be set once.
*/
boolean_t
zfs_prop_setonce(zfs_prop_t prop)
{
return (zfs_prop_table[prop].pd_attr == PROP_ONETIME);
}

/*
Expand Down Expand Up @@ -645,7 +667,8 @@ zpool_prop_to_name(zpool_prop_t prop)
int
zfs_prop_inheritable(zfs_prop_t prop)
{
return (zfs_prop_table[prop].pd_attr == PROP_INHERIT);
return (zfs_prop_table[prop].pd_attr == PROP_INHERIT ||
zfs_prop_table[prop].pd_attr == PROP_ONETIME);
}

/*
Expand Down
30 changes: 25 additions & 5 deletions usr/src/lib/libzfs/common/libzfs_dataset.c
Original file line number Diff line number Diff line change
Expand Up @@ -694,7 +694,7 @@ bootfs_poolname_valid(char *pool, char *bootfs)
*/
nvlist_t *
zfs_validate_properties(libzfs_handle_t *hdl, zfs_type_t type, char *pool_name,
nvlist_t *nvl, uint64_t zoned, zfs_handle_t *zhp, const char *errbuf)
nvlist_t *nvl, uint64_t zoned, zfs_handle_t *zhp, const char *errbuf, boolean_t creating)
{
nvpair_t *elem;
const char *propname;
Expand Down Expand Up @@ -780,7 +780,7 @@ zfs_validate_properties(libzfs_handle_t *hdl, zfs_type_t type, char *pool_name,
}

if (zfs_prop_readonly(prop) &&
(prop != ZFS_PROP_VOLBLOCKSIZE || zhp != NULL)) {
(!zfs_prop_setonce(prop) || (creating == B_FALSE))) {
zfs_error_aux(hdl,
dgettext(TEXT_DOMAIN, "'%s' is readonly"),
propname);
Expand Down Expand Up @@ -1036,6 +1036,26 @@ zfs_validate_properties(libzfs_handle_t *hdl, zfs_type_t type, char *pool_name,

break;
#endif /* !__APPLE__ */

case ZPOOL_PROP_ASHIFT:
if (creating == B_FALSE) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"property '%s' can only be set at "
"creation time"), propname);
(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
goto error;
}

if (intval != 0 && (intval < 9 || intval > 17)) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"property '%s' number %d is invalid."),
propname, intval);
(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
goto error;
}

break;

case ZPOOL_PROP_BOOTFS:
/*
* bootfs property value has to be a dataset name and
Expand Down Expand Up @@ -1848,7 +1868,7 @@ zfs_prop_set(zfs_handle_t *zhp, const char *propname, const char *propval)
}

if ((realprops = zfs_validate_properties(hdl, zhp->zfs_type, NULL, nvl,
zfs_prop_get_int(zhp, ZFS_PROP_ZONED), zhp, errbuf)) == NULL)
zfs_prop_get_int(zhp, ZFS_PROP_ZONED), zhp, errbuf, B_FALSE)) == NULL)
goto error;
nvlist_free(nvl);
nvl = realprops;
Expand Down Expand Up @@ -2835,7 +2855,7 @@ zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type,
zc.zc_objset_type = DMU_OST_ZFS;

if (props && (props = zfs_validate_properties(hdl, type, NULL, props,
zoned, NULL, errbuf)) == 0)
zoned, NULL, errbuf, B_TRUE)) == 0)
return (-1);

if (type == ZFS_TYPE_VOLUME) {
Expand Down Expand Up @@ -3120,7 +3140,7 @@ zfs_clone(zfs_handle_t *zhp, const char *target, nvlist_t *props)

if (props) {
if ((props = zfs_validate_properties(hdl, type, NULL, props,
zoned, zhp, errbuf)) == NULL)
zoned, zhp, errbuf, B_TRUE)) == NULL)
return (-1);

if (zcmd_write_src_nvlist(hdl, &zc, props, NULL) != 0) {
Expand Down
2 changes: 1 addition & 1 deletion usr/src/lib/libzfs/common/libzfs_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ zfs_prop_t zfs_prop_iter_common(zfs_prop_f, void *, zfs_type_t, boolean_t,
zfs_prop_t zfs_name_to_prop_common(const char *, zfs_type_t);

nvlist_t *zfs_validate_properties(libzfs_handle_t *, zfs_type_t, char *,
nvlist_t *, uint64_t, zfs_handle_t *zhp, const char *errbuf);
nvlist_t *, uint64_t, zfs_handle_t *zhp, const char *errbuf, boolean_t creating);

typedef struct prop_changelist prop_changelist_t;

Expand Down
Loading

0 comments on commit f38897e

Please sign in to comment.