libzfs_core.c revision c3d26abc9ee97b4f60233556aadeb57e0bd30bb9
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * CDDL HEADER START
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * The contents of this file are subject to the terms of the
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Common Development and Distribution License (the "License").
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * You may not use this file except in compliance with the License.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * See the License for the specific language governing permissions
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * and limitations under the License.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * When distributing Covered Code, include this CDDL HEADER in each
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * If applicable, add the following below this CDDL HEADER, with the
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * fields enclosed by brackets "[]" replaced with your own identifying
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * information: Portions Copyright [yyyy] [name of copyright owner]
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * CDDL HEADER END
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Copyright (c) 2013 Steven Hartland. All rights reserved.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Copyright (c) 2014 Integros [integros.com]
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * LibZFS_Core (lzc) is intended to replace most functionality in libzfs.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * It has the following characteristics:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * - Thread Safe. libzfs_core is accessible concurrently from multiple
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * threads. This is accomplished primarily by avoiding global data
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * (e.g. caching). Since it's thread-safe, there is no reason for a
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * process to have multiple libzfs "instances". Therefore, we store
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * our few pieces of data (e.g. the file descriptor) in global
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * variables. The fd is reference-counted so that the libzfs_core
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * library can be "initialized" multiple times (e.g. by different
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * consumers within the same process).
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * - Committed Interface. The libzfs_core interface will be committed,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * therefore consumers can compile against it and be confident that
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * their code will continue to work on future releases of this code.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Currently, the interface is Evolving (not Committed), but we intend
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * to commit to it once it is more complete and we determine that it
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * meets the needs of all consumers.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * - Programatic Error Handling. libzfs_core communicates errors with
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * defined error numbers, and doesn't print anything to stdout/stderr.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * - Thin Layer. libzfs_core is a thin layer, marshaling arguments
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * to/from the kernel ioctls. There is generally a 1:1 correspondence
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * between libzfs_core functions and ioctls to /dev/zfs.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * - Clear Atomicity. Because libzfs_core functions are generally 1:1
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * with kernel ioctls, and kernel ioctls are general atomic, each
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * libzfs_core function is atomic. For example, creating multiple
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * snapshots with a single call to lzc_snapshot() is atomic -- it
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * can't fail with only some of the requested snapshots created, even
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * in the event of power loss or system crash.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * - Continued libzfs Support. Some higher-level operations (e.g.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * support for "zfs send -R") are too complicated to fit the scope of
#include <libzfs_core.h>
#include <ctype.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
static int g_fd;
static int g_refcount;
libzfs_core_init(void)
if (g_refcount == 0) {
if (g_fd < 0) {
return (errno);
g_refcount++;
libzfs_core_fini(void)
g_refcount--;
if (g_refcount == 0)
int error = 0;
char *packed;
goto out;
goto out;
out:
return (error);
int error;
return (error);
int error;
return (error);
int error;
return (error);
int error;
if (defer)
return (error);
int err;
char *atp;
return (EINVAL);
if (err == 0)
return (err);
int error;
return (error);
int error;
return (error);
int err;
return (err);
int err;
if (err == 0)
return (err);
int rv;
} while (rv > 0);
return (EIO);
char *atp;
int error;
return (EINVAL);
return (ENOENT);
if (error != 0)
goto out;
if (error != 0)
out:
return (error);
return (EINVAL);
begin_record));
int err;
return (err);
int error;
return (error);
int error;
return (error);