mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 02:27:36 +03:00
zfs: replace uu_avl with sys/avl
Lets just use the AVL implementation we use everywhere else. Sponsored-by: https://despairlabs.com/sponsor/ Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Rob Norris <robn@despairlabs.com> Closes #17934
This commit is contained in:
committed by
Brian Behlendorf
parent
e63d026b91
commit
b593748287
@@ -5,14 +5,12 @@ CPPCHECKTARGETS += libuutil.la
|
||||
|
||||
libuutil_la_SOURCES = \
|
||||
%D%/uu_alloc.c \
|
||||
%D%/uu_avl.c \
|
||||
%D%/uu_ident.c \
|
||||
%D%/uu_list.c \
|
||||
%D%/uu_misc.c \
|
||||
%D%/uu_string.c
|
||||
|
||||
libuutil_la_LIBADD = \
|
||||
libavl.la \
|
||||
libspl.la
|
||||
|
||||
libuutil_la_LIBADD += $(LTLIBINTL)
|
||||
|
||||
@@ -31,12 +31,12 @@
|
||||
*/
|
||||
|
||||
#include <libintl.h>
|
||||
#include <libuutil.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <zone.h>
|
||||
#include <sys/avl.h>
|
||||
|
||||
#include <libzfs.h>
|
||||
|
||||
@@ -70,15 +70,14 @@ typedef struct prop_changenode {
|
||||
int cn_mounted;
|
||||
int cn_zoned;
|
||||
boolean_t cn_needpost; /* is postfix() needed? */
|
||||
uu_avl_node_t cn_treenode;
|
||||
avl_node_t cn_treenode;
|
||||
} prop_changenode_t;
|
||||
|
||||
struct prop_changelist {
|
||||
zfs_prop_t cl_prop;
|
||||
zfs_prop_t cl_realprop;
|
||||
zfs_prop_t cl_shareprop; /* used with sharenfs/sharesmb */
|
||||
uu_avl_pool_t *cl_pool;
|
||||
uu_avl_t *cl_tree;
|
||||
avl_tree_t cl_tree;
|
||||
boolean_t cl_waslegacy;
|
||||
boolean_t cl_allchildren;
|
||||
boolean_t cl_alldependents;
|
||||
@@ -97,7 +96,6 @@ int
|
||||
changelist_prefix(prop_changelist_t *clp)
|
||||
{
|
||||
prop_changenode_t *cn;
|
||||
uu_avl_walk_t *walk;
|
||||
int ret = 0;
|
||||
const enum sa_protocol smb[] = {SA_PROTOCOL_SMB, SA_NO_PROTOCOL};
|
||||
boolean_t commit_smb_shares = B_FALSE;
|
||||
@@ -115,10 +113,8 @@ changelist_prefix(prop_changelist_t *clp)
|
||||
if (clp->cl_gflags & CL_GATHER_DONT_UNMOUNT)
|
||||
return (0);
|
||||
|
||||
if ((walk = uu_avl_walk_start(clp->cl_tree, UU_WALK_ROBUST)) == NULL)
|
||||
return (-1);
|
||||
|
||||
while ((cn = uu_avl_walk_next(walk)) != NULL) {
|
||||
for (cn = avl_first(&clp->cl_tree); cn != NULL;
|
||||
cn = AVL_NEXT(&clp->cl_tree, cn)) {
|
||||
|
||||
/* if a previous loop failed, set the remaining to false */
|
||||
if (ret == -1) {
|
||||
@@ -159,7 +155,6 @@ changelist_prefix(prop_changelist_t *clp)
|
||||
|
||||
if (commit_smb_shares)
|
||||
zfs_commit_shares(smb);
|
||||
uu_avl_walk_end(walk);
|
||||
|
||||
if (ret == -1)
|
||||
(void) changelist_postfix(clp);
|
||||
@@ -179,7 +174,6 @@ int
|
||||
changelist_postfix(prop_changelist_t *clp)
|
||||
{
|
||||
prop_changenode_t *cn;
|
||||
uu_avl_walk_t *walk;
|
||||
char shareopts[ZFS_MAXPROPLEN];
|
||||
boolean_t commit_smb_shares = B_FALSE;
|
||||
boolean_t commit_nfs_shares = B_FALSE;
|
||||
@@ -199,7 +193,7 @@ changelist_postfix(prop_changelist_t *clp)
|
||||
* location), or have explicit mountpoints set (in which case they won't
|
||||
* be in the changelist).
|
||||
*/
|
||||
if ((cn = uu_avl_last(clp->cl_tree)) == NULL)
|
||||
if ((cn = avl_last(&clp->cl_tree)) == NULL)
|
||||
return (0);
|
||||
|
||||
if (clp->cl_prop == ZFS_PROP_MOUNTPOINT &&
|
||||
@@ -211,11 +205,8 @@ changelist_postfix(prop_changelist_t *clp)
|
||||
* datasets before mounting the children. We walk all datasets even if
|
||||
* there are errors.
|
||||
*/
|
||||
if ((walk = uu_avl_walk_start(clp->cl_tree,
|
||||
UU_WALK_REVERSE | UU_WALK_ROBUST)) == NULL)
|
||||
return (-1);
|
||||
|
||||
while ((cn = uu_avl_walk_next(walk)) != NULL) {
|
||||
for (cn = avl_last(&clp->cl_tree); cn != NULL;
|
||||
cn = AVL_PREV(&clp->cl_tree, cn)) {
|
||||
|
||||
boolean_t sharenfs;
|
||||
boolean_t sharesmb;
|
||||
@@ -299,7 +290,6 @@ changelist_postfix(prop_changelist_t *clp)
|
||||
*p++ = SA_PROTOCOL_SMB;
|
||||
*p++ = SA_NO_PROTOCOL;
|
||||
zfs_commit_shares(proto);
|
||||
uu_avl_walk_end(walk);
|
||||
|
||||
return (0);
|
||||
}
|
||||
@@ -334,13 +324,10 @@ void
|
||||
changelist_rename(prop_changelist_t *clp, const char *src, const char *dst)
|
||||
{
|
||||
prop_changenode_t *cn;
|
||||
uu_avl_walk_t *walk;
|
||||
char newname[ZFS_MAX_DATASET_NAME_LEN];
|
||||
|
||||
if ((walk = uu_avl_walk_start(clp->cl_tree, UU_WALK_ROBUST)) == NULL)
|
||||
return;
|
||||
|
||||
while ((cn = uu_avl_walk_next(walk)) != NULL) {
|
||||
for (cn = avl_first(&clp->cl_tree); cn != NULL;
|
||||
cn = AVL_NEXT(&clp->cl_tree, cn)) {
|
||||
/*
|
||||
* Do not rename a clone that's not in the source hierarchy.
|
||||
*/
|
||||
@@ -359,8 +346,6 @@ changelist_rename(prop_changelist_t *clp, const char *src, const char *dst)
|
||||
(void) strlcpy(cn->cn_handle->zfs_name, newname,
|
||||
sizeof (cn->cn_handle->zfs_name));
|
||||
}
|
||||
|
||||
uu_avl_walk_end(walk);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -371,24 +356,20 @@ int
|
||||
changelist_unshare(prop_changelist_t *clp, const enum sa_protocol *proto)
|
||||
{
|
||||
prop_changenode_t *cn;
|
||||
uu_avl_walk_t *walk;
|
||||
int ret = 0;
|
||||
|
||||
if (clp->cl_prop != ZFS_PROP_SHARENFS &&
|
||||
clp->cl_prop != ZFS_PROP_SHARESMB)
|
||||
return (0);
|
||||
|
||||
if ((walk = uu_avl_walk_start(clp->cl_tree, UU_WALK_ROBUST)) == NULL)
|
||||
return (-1);
|
||||
|
||||
while ((cn = uu_avl_walk_next(walk)) != NULL) {
|
||||
for (cn = avl_first(&clp->cl_tree); cn != NULL;
|
||||
cn = AVL_NEXT(&clp->cl_tree, cn)) {
|
||||
if (zfs_unshare(cn->cn_handle, NULL, proto) != 0)
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
for (const enum sa_protocol *p = proto; *p != SA_NO_PROTOCOL; ++p)
|
||||
sa_commit_shares(*p);
|
||||
uu_avl_walk_end(walk);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
@@ -411,22 +392,16 @@ void
|
||||
changelist_remove(prop_changelist_t *clp, const char *name)
|
||||
{
|
||||
prop_changenode_t *cn;
|
||||
uu_avl_walk_t *walk;
|
||||
|
||||
if ((walk = uu_avl_walk_start(clp->cl_tree, UU_WALK_ROBUST)) == NULL)
|
||||
return;
|
||||
|
||||
while ((cn = uu_avl_walk_next(walk)) != NULL) {
|
||||
for (cn = avl_first(&clp->cl_tree); cn != NULL;
|
||||
cn = AVL_NEXT(&clp->cl_tree, cn)) {
|
||||
if (strcmp(cn->cn_handle->zfs_name, name) == 0) {
|
||||
uu_avl_remove(clp->cl_tree, cn);
|
||||
avl_remove(&clp->cl_tree, cn);
|
||||
zfs_close(cn->cn_handle);
|
||||
free(cn);
|
||||
uu_avl_walk_end(walk);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
uu_avl_walk_end(walk);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -436,26 +411,14 @@ void
|
||||
changelist_free(prop_changelist_t *clp)
|
||||
{
|
||||
prop_changenode_t *cn;
|
||||
void *cookie = NULL;
|
||||
|
||||
if (clp->cl_tree) {
|
||||
uu_avl_walk_t *walk;
|
||||
|
||||
if ((walk = uu_avl_walk_start(clp->cl_tree,
|
||||
UU_WALK_ROBUST)) == NULL)
|
||||
return;
|
||||
|
||||
while ((cn = uu_avl_walk_next(walk)) != NULL) {
|
||||
uu_avl_remove(clp->cl_tree, cn);
|
||||
zfs_close(cn->cn_handle);
|
||||
free(cn);
|
||||
}
|
||||
|
||||
uu_avl_walk_end(walk);
|
||||
uu_avl_destroy(clp->cl_tree);
|
||||
while ((cn = avl_destroy_nodes(&clp->cl_tree, &cookie)) != NULL) {
|
||||
zfs_close(cn->cn_handle);
|
||||
free(cn);
|
||||
}
|
||||
if (clp->cl_pool)
|
||||
uu_avl_pool_destroy(clp->cl_pool);
|
||||
|
||||
avl_destroy(&clp->cl_tree);
|
||||
free(clp);
|
||||
}
|
||||
|
||||
@@ -467,7 +430,7 @@ changelist_add_mounted(zfs_handle_t *zhp, void *data)
|
||||
{
|
||||
prop_changelist_t *clp = data;
|
||||
prop_changenode_t *cn;
|
||||
uu_avl_index_t idx;
|
||||
avl_index_t idx;
|
||||
|
||||
ASSERT3U(clp->cl_prop, ==, ZFS_PROP_MOUNTPOINT);
|
||||
|
||||
@@ -483,10 +446,8 @@ changelist_add_mounted(zfs_handle_t *zhp, void *data)
|
||||
if (getzoneid() == GLOBAL_ZONEID && cn->cn_zoned)
|
||||
clp->cl_haszonedchild = B_TRUE;
|
||||
|
||||
uu_avl_node_init(cn, &cn->cn_treenode, clp->cl_pool);
|
||||
|
||||
if (uu_avl_find(clp->cl_tree, cn, NULL, &idx) == NULL) {
|
||||
uu_avl_insert(clp->cl_tree, cn, idx);
|
||||
if (avl_find(&clp->cl_tree, cn, &idx) == NULL) {
|
||||
avl_insert(&clp->cl_tree, cn, idx);
|
||||
} else {
|
||||
free(cn);
|
||||
zfs_close(zhp);
|
||||
@@ -553,12 +514,9 @@ change_one(zfs_handle_t *zhp, void *data)
|
||||
if (getzoneid() == GLOBAL_ZONEID && cn->cn_zoned)
|
||||
clp->cl_haszonedchild = B_TRUE;
|
||||
|
||||
uu_avl_node_init(cn, &cn->cn_treenode, clp->cl_pool);
|
||||
|
||||
uu_avl_index_t idx;
|
||||
|
||||
if (uu_avl_find(clp->cl_tree, cn, NULL, &idx) == NULL) {
|
||||
uu_avl_insert(clp->cl_tree, cn, idx);
|
||||
avl_index_t idx;
|
||||
if (avl_find(&clp->cl_tree, cn, &idx) == NULL) {
|
||||
avl_insert(&clp->cl_tree, cn, idx);
|
||||
} else {
|
||||
free(cn);
|
||||
cn = NULL;
|
||||
@@ -610,11 +568,11 @@ compare_props(const void *a, const void *b, zfs_prop_t prop)
|
||||
else if (!haspropa && !haspropb)
|
||||
return (0);
|
||||
else
|
||||
return (strcmp(propb, propa));
|
||||
return (TREE_ISIGN(strcmp(propb, propa)));
|
||||
}
|
||||
|
||||
static int
|
||||
compare_mountpoints(const void *a, const void *b, void *unused)
|
||||
compare_mountpoints(const void *a, const void *b)
|
||||
{
|
||||
/*
|
||||
* When unsharing or unmounting filesystems, we need to do it in
|
||||
@@ -622,14 +580,12 @@ compare_mountpoints(const void *a, const void *b, void *unused)
|
||||
* hierarchy that is different from the dataset hierarchy, and still
|
||||
* allow it to be changed.
|
||||
*/
|
||||
(void) unused;
|
||||
return (compare_props(a, b, ZFS_PROP_MOUNTPOINT));
|
||||
}
|
||||
|
||||
static int
|
||||
compare_dataset_names(const void *a, const void *b, void *unused)
|
||||
compare_dataset_names(const void *a, const void *b)
|
||||
{
|
||||
(void) unused;
|
||||
return (compare_props(a, b, ZFS_PROP_NAME));
|
||||
}
|
||||
|
||||
@@ -671,28 +627,14 @@ changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int gather_flags,
|
||||
}
|
||||
}
|
||||
|
||||
clp->cl_pool = uu_avl_pool_create("changelist_pool",
|
||||
avl_create(&clp->cl_tree,
|
||||
legacy ? compare_dataset_names : compare_mountpoints,
|
||||
sizeof (prop_changenode_t),
|
||||
offsetof(prop_changenode_t, cn_treenode),
|
||||
legacy ? compare_dataset_names : compare_mountpoints, 0);
|
||||
if (clp->cl_pool == NULL) {
|
||||
assert(uu_error() == UU_ERROR_NO_MEMORY);
|
||||
(void) zfs_error(zhp->zfs_hdl, EZFS_NOMEM, "internal error");
|
||||
changelist_free(clp);
|
||||
return (NULL);
|
||||
}
|
||||
offsetof(prop_changenode_t, cn_treenode));
|
||||
|
||||
clp->cl_tree = uu_avl_create(clp->cl_pool, NULL, UU_DEFAULT);
|
||||
clp->cl_gflags = gather_flags;
|
||||
clp->cl_mflags = mnt_flags;
|
||||
|
||||
if (clp->cl_tree == NULL) {
|
||||
assert(uu_error() == UU_ERROR_NO_MEMORY);
|
||||
(void) zfs_error(zhp->zfs_hdl, EZFS_NOMEM, "internal error");
|
||||
changelist_free(clp);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* If this is a rename or the 'zoned' property, we pretend we're
|
||||
* changing the mountpoint and flag it so we can catch all children in
|
||||
@@ -778,10 +720,9 @@ changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int gather_flags,
|
||||
cn->cn_zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED);
|
||||
cn->cn_needpost = B_TRUE;
|
||||
|
||||
uu_avl_node_init(cn, &cn->cn_treenode, clp->cl_pool);
|
||||
uu_avl_index_t idx;
|
||||
if (uu_avl_find(clp->cl_tree, cn, NULL, &idx) == NULL) {
|
||||
uu_avl_insert(clp->cl_tree, cn, idx);
|
||||
avl_index_t idx;
|
||||
if (avl_find(&clp->cl_tree, cn, &idx) == NULL) {
|
||||
avl_insert(&clp->cl_tree, cn, idx);
|
||||
} else {
|
||||
free(cn);
|
||||
zfs_close(temp);
|
||||
|
||||
+20
-51
@@ -47,55 +47,37 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <libintl.h>
|
||||
#include <libuutil.h>
|
||||
|
||||
#include "libzfs_impl.h"
|
||||
|
||||
typedef struct config_node {
|
||||
char *cn_name;
|
||||
nvlist_t *cn_config;
|
||||
uu_avl_node_t cn_avl;
|
||||
avl_node_t cn_avl;
|
||||
} config_node_t;
|
||||
|
||||
static int
|
||||
config_node_compare(const void *a, const void *b, void *unused)
|
||||
config_node_compare(const void *a, const void *b)
|
||||
{
|
||||
(void) unused;
|
||||
const config_node_t *ca = (config_node_t *)a;
|
||||
const config_node_t *cb = (config_node_t *)b;
|
||||
|
||||
int ret = strcmp(ca->cn_name, cb->cn_name);
|
||||
|
||||
if (ret < 0)
|
||||
return (-1);
|
||||
else if (ret > 0)
|
||||
return (1);
|
||||
else
|
||||
return (0);
|
||||
return (TREE_ISIGN(strcmp(ca->cn_name, cb->cn_name)));
|
||||
}
|
||||
|
||||
void
|
||||
namespace_clear(libzfs_handle_t *hdl)
|
||||
{
|
||||
if (hdl->libzfs_ns_avl) {
|
||||
config_node_t *cn;
|
||||
void *cookie = NULL;
|
||||
config_node_t *cn;
|
||||
void *cookie = NULL;
|
||||
|
||||
while ((cn = uu_avl_teardown(hdl->libzfs_ns_avl,
|
||||
&cookie)) != NULL) {
|
||||
nvlist_free(cn->cn_config);
|
||||
free(cn->cn_name);
|
||||
free(cn);
|
||||
}
|
||||
|
||||
uu_avl_destroy(hdl->libzfs_ns_avl);
|
||||
hdl->libzfs_ns_avl = NULL;
|
||||
while ((cn = avl_destroy_nodes(&hdl->libzfs_ns_avl, &cookie)) != NULL) {
|
||||
nvlist_free(cn->cn_config);
|
||||
free(cn->cn_name);
|
||||
free(cn);
|
||||
}
|
||||
|
||||
if (hdl->libzfs_ns_avlpool) {
|
||||
uu_avl_pool_destroy(hdl->libzfs_ns_avlpool);
|
||||
hdl->libzfs_ns_avlpool = NULL;
|
||||
}
|
||||
avl_destroy(&hdl->libzfs_ns_avl);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -111,20 +93,8 @@ namespace_reload(libzfs_handle_t *hdl)
|
||||
void *cookie;
|
||||
|
||||
if (hdl->libzfs_ns_gen == 0) {
|
||||
/*
|
||||
* This is the first time we've accessed the configuration
|
||||
* cache. Initialize the AVL tree and then fall through to the
|
||||
* common code.
|
||||
*/
|
||||
if ((hdl->libzfs_ns_avlpool = uu_avl_pool_create("config_pool",
|
||||
sizeof (config_node_t),
|
||||
offsetof(config_node_t, cn_avl),
|
||||
config_node_compare, UU_DEFAULT)) == NULL)
|
||||
return (no_memory(hdl));
|
||||
|
||||
if ((hdl->libzfs_ns_avl = uu_avl_create(hdl->libzfs_ns_avlpool,
|
||||
NULL, UU_DEFAULT)) == NULL)
|
||||
return (no_memory(hdl));
|
||||
avl_create(&hdl->libzfs_ns_avl, config_node_compare,
|
||||
sizeof (config_node_t), offsetof(config_node_t, cn_avl));
|
||||
}
|
||||
|
||||
zcmd_alloc_dst_nvlist(hdl, &zc, 0);
|
||||
@@ -167,7 +137,7 @@ namespace_reload(libzfs_handle_t *hdl)
|
||||
* Clear out any existing configuration information.
|
||||
*/
|
||||
cookie = NULL;
|
||||
while ((cn = uu_avl_teardown(hdl->libzfs_ns_avl, &cookie)) != NULL) {
|
||||
while ((cn = avl_destroy_nodes(&hdl->libzfs_ns_avl, &cookie)) != NULL) {
|
||||
nvlist_free(cn->cn_config);
|
||||
free(cn->cn_name);
|
||||
free(cn);
|
||||
@@ -176,7 +146,7 @@ namespace_reload(libzfs_handle_t *hdl)
|
||||
elem = NULL;
|
||||
while ((elem = nvlist_next_nvpair(config, elem)) != NULL) {
|
||||
nvlist_t *child;
|
||||
uu_avl_index_t where;
|
||||
avl_index_t where;
|
||||
|
||||
cn = zfs_alloc(hdl, sizeof (config_node_t));
|
||||
cn->cn_name = zfs_strdup(hdl, nvpair_name(elem));
|
||||
@@ -187,10 +157,9 @@ namespace_reload(libzfs_handle_t *hdl)
|
||||
nvlist_free(config);
|
||||
return (no_memory(hdl));
|
||||
}
|
||||
verify(uu_avl_find(hdl->libzfs_ns_avl, cn, NULL, &where)
|
||||
== NULL);
|
||||
verify(avl_find(&hdl->libzfs_ns_avl, cn, &where) == NULL);
|
||||
|
||||
uu_avl_insert(hdl->libzfs_ns_avl, cn, where);
|
||||
avl_insert(&hdl->libzfs_ns_avl, cn, where);
|
||||
}
|
||||
|
||||
nvlist_free(config);
|
||||
@@ -400,8 +369,8 @@ zpool_iter(libzfs_handle_t *hdl, zpool_iter_f func, void *data)
|
||||
return (-1);
|
||||
|
||||
hdl->libzfs_pool_iter++;
|
||||
for (cn = uu_avl_first(hdl->libzfs_ns_avl); cn != NULL;
|
||||
cn = uu_avl_next(hdl->libzfs_ns_avl, cn)) {
|
||||
for (cn = avl_first(&hdl->libzfs_ns_avl); cn != NULL;
|
||||
cn = AVL_NEXT(&hdl->libzfs_ns_avl, cn)) {
|
||||
|
||||
if (zpool_skip_pool(cn->cn_name))
|
||||
continue;
|
||||
@@ -438,8 +407,8 @@ zfs_iter_root(libzfs_handle_t *hdl, zfs_iter_f func, void *data)
|
||||
if (namespace_reload(hdl) != 0)
|
||||
return (-1);
|
||||
|
||||
for (cn = uu_avl_first(hdl->libzfs_ns_avl); cn != NULL;
|
||||
cn = uu_avl_next(hdl->libzfs_ns_avl, cn)) {
|
||||
for (cn = avl_first(&hdl->libzfs_ns_avl); cn != NULL;
|
||||
cn = AVL_NEXT(&hdl->libzfs_ns_avl, cn)) {
|
||||
|
||||
if (zpool_skip_pool(cn->cn_name))
|
||||
continue;
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
#include <sys/zfs_ioctl.h>
|
||||
#include <regex.h>
|
||||
|
||||
#include <libuutil.h>
|
||||
#include <libzfs.h>
|
||||
#include <libshare.h>
|
||||
#include <libzfs_core.h>
|
||||
@@ -51,8 +50,7 @@ struct libzfs_handle {
|
||||
int libzfs_error;
|
||||
int libzfs_fd;
|
||||
zpool_handle_t *libzfs_pool_handles;
|
||||
uu_avl_pool_t *libzfs_ns_avlpool;
|
||||
uu_avl_t *libzfs_ns_avl;
|
||||
avl_tree_t libzfs_ns_avl;
|
||||
uint64_t libzfs_ns_gen;
|
||||
int libzfs_desc_active;
|
||||
char libzfs_action[1024];
|
||||
|
||||
Reference in New Issue
Block a user