Print this page
NEX-3558 KRRP Integration
OS-195 itadm needs an easily parsable output mode
OS-207 SUP-817 causes lint warnings in zpool_main.c
Reviewed by: Alek Pinchuk <alek.pinchuk@nexena.com>
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
Reviewed by: Albert Lee <albert.lee@nexenta.com>
re #12585 rb4049 ZFS++ work port - refactoring to improve separation of open/closed code, bug fixes, performance improvements - open code
Bug 11205: add missing libzfs_closed_stubs.c to fix opensource-only build.
ZFS plus work: special vdevs, cos, cos/vdev properties
*** 19,28 ****
--- 19,29 ----
* CDDL HEADER END
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2013, 2015 by Delphix. All rights reserved.
* Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>.
*/
/*
*** 385,395 ****
* /dev/dsk/xxx Complete disk path
* /xxx Full path to file
* xxx Shorthand for /dev/dsk/xxx
*/
static nvlist_t *
! make_leaf_vdev(const char *arg, uint64_t is_log)
{
char path[MAXPATHLEN];
struct stat64 statbuf;
nvlist_t *vdev = NULL;
char *type = NULL;
--- 386,396 ----
* /dev/dsk/xxx Complete disk path
* /xxx Full path to file
* xxx Shorthand for /dev/dsk/xxx
*/
static nvlist_t *
! make_leaf_vdev(const char *arg, uint64_t is_log, uint64_t is_special)
{
char path[MAXPATHLEN];
struct stat64 statbuf;
nvlist_t *vdev = NULL;
char *type = NULL;
*** 469,478 ****
--- 470,481 ----
*/
verify(nvlist_alloc(&vdev, NV_UNIQUE_NAME, 0) == 0);
verify(nvlist_add_string(vdev, ZPOOL_CONFIG_PATH, path) == 0);
verify(nvlist_add_string(vdev, ZPOOL_CONFIG_TYPE, type) == 0);
verify(nvlist_add_uint64(vdev, ZPOOL_CONFIG_IS_LOG, is_log) == 0);
+ verify(nvlist_add_uint64(vdev, ZPOOL_CONFIG_IS_SPECIAL,
+ is_special) == 0);
if (strcmp(type, VDEV_TYPE_DISK) == 0)
verify(nvlist_add_uint64(vdev, ZPOOL_CONFIG_WHOLE_DISK,
(uint64_t)wholedisk) == 0);
/*
*** 626,640 ****
verify(nvlist_lookup_string(cnv,
ZPOOL_CONFIG_TYPE, &childtype) == 0);
/*
* If this is a replacing or spare vdev, then
! * get the real first child of the vdev: do this
! * in a loop because replacing and spare vdevs
! * can be nested.
*/
! while (strcmp(childtype,
VDEV_TYPE_REPLACING) == 0 ||
strcmp(childtype, VDEV_TYPE_SPARE) == 0) {
nvlist_t **rchild;
uint_t rchildren;
--- 629,641 ----
verify(nvlist_lookup_string(cnv,
ZPOOL_CONFIG_TYPE, &childtype) == 0);
/*
* If this is a replacing or spare vdev, then
! * get the real first child of the vdev.
*/
! if (strcmp(childtype,
VDEV_TYPE_REPLACING) == 0 ||
strcmp(childtype, VDEV_TYPE_SPARE) == 0) {
nvlist_t **rchild;
uint_t rchildren;
*** 1181,1190 ****
--- 1182,1197 ----
if (mindev != NULL)
*mindev = 1;
return (VDEV_TYPE_L2CACHE);
}
+ if (strcmp(type, "special") == 0) {
+ if (mindev != NULL)
+ *mindev = 1;
+ return (VDEV_TYPE_SPECIAL);
+ }
+
return (NULL);
}
/*
* Construct a syntactically valid vdev specification,
*** 1195,1207 ****
nvlist_t *
construct_spec(int argc, char **argv)
{
nvlist_t *nvroot, *nv, **top, **spares, **l2cache;
int t, toplevels, mindev, maxdev, nspares, nlogs, nl2cache;
const char *type;
! uint64_t is_log;
! boolean_t seen_logs;
top = NULL;
toplevels = 0;
spares = NULL;
l2cache = NULL;
--- 1202,1215 ----
nvlist_t *
construct_spec(int argc, char **argv)
{
nvlist_t *nvroot, *nv, **top, **spares, **l2cache;
int t, toplevels, mindev, maxdev, nspares, nlogs, nl2cache;
+ int nspecial = 0;
const char *type;
! boolean_t is_log, seen_logs;
! boolean_t is_special, seen_special;
top = NULL;
toplevels = 0;
spares = NULL;
l2cache = NULL;
*** 1208,1217 ****
--- 1216,1227 ----
nspares = 0;
nlogs = 0;
nl2cache = 0;
is_log = B_FALSE;
seen_logs = B_FALSE;
+ is_special = B_FALSE;
+ seen_special = B_FALSE;
while (argc > 0) {
nv = NULL;
/*
*** 1229,1238 ****
--- 1239,1249 ----
"specification: 'spare' can be "
"specified only once\n"));
return (NULL);
}
is_log = B_FALSE;
+ is_special = B_FALSE;
}
if (strcmp(type, VDEV_TYPE_LOG) == 0) {
if (seen_logs) {
(void) fprintf(stderr,
*** 1241,1250 ****
--- 1252,1262 ----
"specified only once\n"));
return (NULL);
}
seen_logs = B_TRUE;
is_log = B_TRUE;
+ is_special = B_FALSE;
argc--;
argv++;
/*
* A log is not a real grouping device.
* We just set is_log and continue.
*** 1259,1270 ****
--- 1271,1303 ----
"specification: 'cache' can be "
"specified only once\n"));
return (NULL);
}
is_log = B_FALSE;
+ is_special = B_FALSE;
}
+ if (strcmp(type, VDEV_TYPE_SPECIAL) == 0) {
+ if (seen_special) {
+ (void) fprintf(stderr,
+ gettext("invalid vdev "
+ "specification: 'special' can be "
+ "specified only once\n"));
+ return (NULL);
+ }
+ seen_special = B_TRUE;
+ is_log = B_FALSE;
+ is_special = B_TRUE;
+ argc--;
+ argv++;
+ /*
+ * A special is not a real grouping device.
+ * We just set is_special and continue.
+ */
+ continue;
+ }
+
if (is_log) {
if (strcmp(type, VDEV_TYPE_MIRROR) != 0) {
(void) fprintf(stderr,
gettext("invalid vdev "
"specification: unsupported 'log' "
*** 1272,1291 ****
return (NULL);
}
nlogs++;
}
for (c = 1; c < argc; c++) {
if (is_grouping(argv[c], NULL, NULL) != NULL)
break;
children++;
child = realloc(child,
children * sizeof (nvlist_t *));
if (child == NULL)
zpool_no_memory();
! if ((nv = make_leaf_vdev(argv[c], B_FALSE))
! == NULL)
return (NULL);
child[children - 1] = nv;
}
if (children < mindev) {
--- 1305,1336 ----
return (NULL);
}
nlogs++;
}
+ if (is_special) {
+ if (strcmp(type, VDEV_TYPE_MIRROR) != 0) {
+ (void) fprintf(stderr,
+ gettext("invalid vdev "
+ "specification: unsupported "
+ "'special' device: %s\n"), type);
+ return (NULL);
+ }
+ nspecial++;
+ }
+
for (c = 1; c < argc; c++) {
if (is_grouping(argv[c], NULL, NULL) != NULL)
break;
children++;
child = realloc(child,
children * sizeof (nvlist_t *));
if (child == NULL)
zpool_no_memory();
! if ((nv = make_leaf_vdev(argv[c],
! (uint64_t)B_FALSE,
! (uint64_t)B_FALSE)) == NULL)
return (NULL);
child[children - 1] = nv;
}
if (children < mindev) {
*** 1317,1327 ****
verify(nvlist_alloc(&nv, NV_UNIQUE_NAME,
0) == 0);
verify(nvlist_add_string(nv, ZPOOL_CONFIG_TYPE,
type) == 0);
verify(nvlist_add_uint64(nv,
! ZPOOL_CONFIG_IS_LOG, is_log) == 0);
if (strcmp(type, VDEV_TYPE_RAIDZ) == 0) {
verify(nvlist_add_uint64(nv,
ZPOOL_CONFIG_NPARITY,
mindev - 1) == 0);
}
--- 1362,1376 ----
verify(nvlist_alloc(&nv, NV_UNIQUE_NAME,
0) == 0);
verify(nvlist_add_string(nv, ZPOOL_CONFIG_TYPE,
type) == 0);
verify(nvlist_add_uint64(nv,
! ZPOOL_CONFIG_IS_LOG,
! (uint64_t)is_log) == 0);
! verify(nvlist_add_uint64(nv,
! ZPOOL_CONFIG_IS_SPECIAL,
! (uint64_t)is_special) == 0);
if (strcmp(type, VDEV_TYPE_RAIDZ) == 0) {
verify(nvlist_add_uint64(nv,
ZPOOL_CONFIG_NPARITY,
mindev - 1) == 0);
}
*** 1336,1349 ****
} else {
/*
* 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)
return (NULL);
if (is_log)
nlogs++;
argc--;
argv++;
}
toplevels++;
--- 1385,1401 ----
} else {
/*
* 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], (uint64_t)is_log,
! (uint64_t)is_special)) == NULL)
return (NULL);
if (is_log)
nlogs++;
+ if (is_special)
+ nspecial++;
argc--;
argv++;
}
toplevels++;
*** 1357,1366 ****
--- 1409,1424 ----
(void) fprintf(stderr, gettext("invalid vdev "
"specification: at least one toplevel vdev must be "
"specified\n"));
return (NULL);
}
+
+ if (seen_special && nspecial == 0) {
+ (void) fprintf(stderr, gettext("invalid vdev specification: "
+ "special requires at least 1 device\n"));
+ return (NULL);
+ }
if (seen_logs && nlogs == 0) {
(void) fprintf(stderr, gettext("invalid vdev specification: "
"log requires at least 1 device\n"));
return (NULL);