libzfs_pool.c revision 5ad820458efd0fdb914baff9c1447c22b819fa23
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * CDDL HEADER START
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * The contents of this file are subject to the terms of the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Common Development and Distribution License (the "License").
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * You may not use this file except in compliance with the License.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * See the License for the specific language governing permissions
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * and limitations under the License.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * When distributing Covered Code, include this CDDL HEADER in each
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * If applicable, add the following below this CDDL HEADER, with the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * fields enclosed by brackets "[]" replaced with your own identifying
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * information: Portions Copyright [yyyy] [name of copyright owner]
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * CDDL HEADER END
c7facc54c4abed9e554ff80225311e6b7048d3c9Bill Taylor * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Use is subject to license terms.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#pragma ident "%Z%%M% %I% %E% SMI"
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Validate the given pool name, optionally putting an extended error message in
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorzpool_name_valid(libzfs_handle_t *hdl, boolean_t isopen, const char *pool)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * The rules for reserved pool names were extended at a later point.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * But we need to support users with existing pools that may now be
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * invalid. So we only check for this expanded set of names during a
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * create (or import), and only in userland.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "name must begin with a letter"));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "name is reserved"));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "pool name is reserved"));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "leading slash in name"));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "empty component in name"));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "trailing slash in name"));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "multiple '@' delimiters in name"));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Set the pool-wide health based on the vdev state of the root vdev.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (nvlist_add_string(config, ZPOOL_CONFIG_POOL_HEALTH, health));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Open a handle to the given pool, even if the pool is currently in the FAULTED
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorzpool_open_canfail(libzfs_handle_t *hdl, const char *pool)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Make sure the pool name is valid.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((zhp = zfs_alloc(hdl, sizeof (zpool_handle_t))) == NULL)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) strlcpy(zhp->zpool_name, pool, sizeof (zhp->zpool_name));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "no such pool"));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Like the above, but silent on error. Used when iterating over pools (because
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the configuration cache may be out of date).
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorzpool_open_silent(libzfs_handle_t *hdl, const char *pool, zpool_handle_t **ret)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((zhp = zfs_alloc(hdl, sizeof (zpool_handle_t))) == NULL)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (-1);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) strlcpy(zhp->zpool_name, pool, sizeof (zhp->zpool_name));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (-1);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Similar to zpool_open_canfail(), but refuses to open pools in the faulted
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorzpool_open(libzfs_handle_t *hdl, const char *pool)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((zhp = zpool_open_canfail(hdl, pool)) == NULL)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dgettext(TEXT_DOMAIN, "cannot open '%s'"), zhp->zpool_name);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Close the handle. Simply frees the memory associated with the handle.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Return the name of the pool.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Return the GUID of the pool.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor verify(nvlist_lookup_uint64(zhp->zpool_config, ZPOOL_CONFIG_POOL_GUID,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Return the version of the pool.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor verify(nvlist_lookup_uint64(zhp->zpool_config, ZPOOL_CONFIG_VERSION,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Return the amount of space currently consumed by the pool.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Return the total space in the pool.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Return the alternate root for this pool, if any.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorzpool_get_root(zpool_handle_t *zhp, char *buf, size_t buflen)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) != 0 ||
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (-1);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Return the state of the pool (ACTIVE or UNAVAILABLE)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Create the named pool, using the provided vdev list. It is assumed
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * that the consumer has already validated the contents of the nvlist, so we
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * don't have to worry about error semantics.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorzpool_create(libzfs_handle_t *hdl, const char *pool, nvlist_t *nvroot,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dgettext(TEXT_DOMAIN, "bad alternate root '%s'"), altroot));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (zcmd_write_src_nvlist(hdl, &zc, nvroot, NULL) != 0)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (-1);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) strlcpy(zc.zc_name, pool, sizeof (zc.zc_name));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) strlcpy(zc.zc_value, altroot, sizeof (zc.zc_value));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_CREATE, &zc) != 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * This can happen if the user has specified the same
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * device multiple times. We can't reliably detect this
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * until we try to add it and see we already have a
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "one or more vdevs refer to the same device"));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * This occurs when one of the devices is below
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * SPA_MINDEVSIZE. Unfortunately, we can't detect which
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * device was the problem device since there's no
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * reliable way to determine device size from userland.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "one or more devices is less than the "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "one or more devices is out of space"));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * If this is an alternate root pool, then we automatically set the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * mountpoint of the root dataset to be '/'.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor verify((zhp = zfs_open(hdl, pool, ZFS_TYPE_ANY)) != NULL);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor verify(zfs_prop_set(zhp, zfs_prop_to_name(ZFS_PROP_MOUNTPOINT),
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Destroy the given pool. It is up to the caller to ensure that there are no
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * datasets left in the pool.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (zfp = zfs_open(zhp->zpool_hdl, zhp->zpool_name,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (-1);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (-1);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_POOL_DESTROY, &zc) != 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "one or more devices is read only"));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (-1);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Add the given vdevs to the pool. The caller must have already performed the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * necessary verification to ensure that the vdev specification is well-formed.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (zpool_get_version(zhp) < ZFS_VERSION_SPARES &&
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool must be "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "upgraded to add hot spares"));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (zcmd_write_src_nvlist(hdl, &zc, nvroot, NULL) != 0)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (-1);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_VDEV_ADD, &zc) != 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * This can happen if the user has specified the same
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * device multiple times. We can't reliably detect this
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * until we try to add it and see we already have a
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "one or more vdevs refer to the same device"));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * This occurrs when one of the devices is below
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * SPA_MINDEVSIZE. Unfortunately, we can't detect which
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * device was the problem device since there's no
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * reliable way to determine device size from userland.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "device is less than the minimum "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "pool must be upgraded to add raidz2 vdevs"));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Exports the pool from the system. The caller must ensure that there are no
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * mounted datasets in the pool.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (-1);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_POOL_EXPORT, &zc) != 0)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (zpool_standard_error(zhp->zpool_hdl, errno,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Import the given pool using the known configuration. The configuration
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * should have come from zpool_find_import(). The 'newname' and 'altroot'
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * parameters control whether the pool is imported with a different name or with
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * an alternate root, respectively.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorzpool_import(libzfs_handle_t *hdl, nvlist_t *config, const char *newname,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dgettext(TEXT_DOMAIN, "bad alternate root '%s'"),
de710d24d2fae4468e64da999e1d952a247f142cJosef 'Jeff' Sipek (void) strlcpy(zc.zc_name, thename, sizeof (zc.zc_name));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) strlcpy(zc.zc_value, altroot, sizeof (zc.zc_value));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (zcmd_write_src_nvlist(hdl, &zc, config, NULL) != 0)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (-1);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_IMPORT, &zc) != 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dgettext(TEXT_DOMAIN, "cannot import '%s' as '%s'"),
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Unsupported version.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * This should never fail, but play it safe anyway.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (zpool_open_silent(hdl, thename, &zhp) != 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Scrub the pool.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorzpool_scrub(zpool_handle_t *zhp, pool_scrub_type_t type)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_POOL_SCRUB, &zc) == 0)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dgettext(TEXT_DOMAIN, "cannot scrub %s"), zc.zc_name);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * 'avail_spare' is set to TRUE if the provided guid refers to an AVAIL
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * spare; but FALSE if its an INUSE spare.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorvdev_to_nvlist_iter(nvlist_t *nv, const char *search, uint64_t guid,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &theguid) == 0);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT, &present) == 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * If the device has never been present since import, the only
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * reliable way to match the vdev is by GUID.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * For whole disks, the internal path has 's0', but the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * path passed in by the user doesn't.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor for (c = 0; c < children; c++)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((ret = vdev_to_nvlist_iter(child[c], search, guid,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor for (c = 0; c < children; c++) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((ret = vdev_to_nvlist_iter(child[c], search, guid,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorzpool_find_vdev(zpool_handle_t *zhp, const char *path, boolean_t *avail_spare)
&nvroot) == 0);
static boolean_t
&nvroot) == 0);
for (i = 0; i < nspares; i++) {
return (B_TRUE);
return (B_FALSE);
switch (errno) {
case EBUSY:
static boolean_t
char *type;
&children) == 0) {
&type) == 0);
return (B_TRUE);
for (c = 0; c < children; c++)
return (B_TRUE);
return (B_FALSE);
int ret;
char *path;
if (replacing)
if (avail_spare)
if (replacing &&
if (replacing &&
if (ret == 0)
switch (errno) {
case ENOTSUP:
if (replacing)
case EINVAL:
case EBUSY:
new_disk);
case EOVERFLOW:
case EDOM:
case ENAMETOOLONG:
if (avail_spare)
switch (errno) {
case ENOTSUP:
case EBUSY:
if (!avail_spare) {
if (path)
path);
if (path) {
if (avail_spare)
int ret;
if (linktype)
return (ret);
int ret;
return (ret);
int ret;
return (ret);
char *minor;
char *path;
int ret;
return (NULL);
if (ret != 0)
return (NULL);
return (NULL);
return (path);
int fd;
return (NULL);
return (ret);
&value) == 0) {
&value) == 0);
char *newpath;
&path) == 0);
if (newdevid)
return (NULL);
return (tmp);
&value) == 0);
zbookmark_compare(const void *a, const void *b)
&count) == 0);
&zc) != 0) {
for (i = 0; i < count; i++) {
sizeof (zbookmark_t)) == 0)
*nelem = j;
for (i = 0; i < count; i++) {
sizeof (zbookmark_t)) == 0)
goto nomem;
goto nomem;
goto nomem;
goto nomem;
goto nomem;
goto nomem;
goto nomem;