libshare: use AVL tree with static data, pass all data in arguments
This makes it so we don't leak a consistent 64 bytes anymore, makes the searches simpler and faster, removes /all allocations/ from the driver (quite trivially, since they were absolutely needless), and makes libshare thread-safe (except, maybe, linux/smb, but that only does pointer-width loads/stores so it's also mostly fine, except for leaking smb_shares) Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz> Closes #13165
This commit is contained in:
parent
4ccbb23971
commit
63ce6dd988
@ -27,6 +27,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <libintl.h>
|
||||
@ -37,139 +38,84 @@
|
||||
#include <libzfs.h>
|
||||
#include <libshare.h>
|
||||
#include "libshare_impl.h"
|
||||
#include "nfs.h"
|
||||
#include "smb.h"
|
||||
|
||||
static sa_share_impl_t alloc_share(const char *zfsname, const char *path);
|
||||
static void free_share(sa_share_impl_t share);
|
||||
#define init_share(zfsname, path, shareopts) \
|
||||
{ \
|
||||
.sa_zfsname = zfsname, \
|
||||
.sa_mountpoint = path, \
|
||||
.sa_shareopts = shareopts, \
|
||||
}
|
||||
#define find_proto(pcol) \
|
||||
/* CSTYLED */ \
|
||||
({ \
|
||||
sa_fstype_t prot = { \
|
||||
.protocol = pcol, \
|
||||
}; \
|
||||
avl_find(&fstypes, &prot, NULL); \
|
||||
})
|
||||
|
||||
static int fstypes_count;
|
||||
static sa_fstype_t *fstypes;
|
||||
static avl_tree_t fstypes;
|
||||
|
||||
sa_fstype_t *
|
||||
register_fstype(const char *name, const sa_share_ops_t *ops)
|
||||
static int
|
||||
fstypes_compar(const void *lhs, const void *rhs)
|
||||
{
|
||||
sa_fstype_t *fstype;
|
||||
|
||||
fstype = calloc(1, sizeof (sa_fstype_t));
|
||||
|
||||
if (fstype == NULL)
|
||||
return (NULL);
|
||||
|
||||
fstype->name = name;
|
||||
fstype->ops = ops;
|
||||
fstype->fsinfo_index = fstypes_count;
|
||||
|
||||
fstypes_count++;
|
||||
|
||||
fstype->next = fstypes;
|
||||
fstypes = fstype;
|
||||
|
||||
return (fstype);
|
||||
const sa_fstype_t *l = lhs, *r = rhs;
|
||||
int cmp = strcmp(l->protocol, r->protocol);
|
||||
return ((0 < cmp) - (cmp < 0));
|
||||
}
|
||||
|
||||
__attribute__((constructor)) static void
|
||||
libshare_init(void)
|
||||
{
|
||||
libshare_nfs_init();
|
||||
libshare_smb_init();
|
||||
avl_create(&fstypes, fstypes_compar,
|
||||
sizeof (sa_fstype_t), offsetof(sa_fstype_t, node));
|
||||
avl_add(&fstypes, &libshare_nfs_type);
|
||||
avl_add(&fstypes, &libshare_smb_type);
|
||||
}
|
||||
|
||||
int
|
||||
sa_enable_share(const char *zfsname, const char *mountpoint,
|
||||
const char *shareopts, const char *protocol)
|
||||
{
|
||||
int rc, ret = SA_OK;
|
||||
boolean_t found_protocol = B_FALSE;
|
||||
sa_fstype_t *fstype;
|
||||
sa_fstype_t *fstype = find_proto(protocol);
|
||||
if (!fstype)
|
||||
return (SA_INVALID_PROTOCOL);
|
||||
|
||||
sa_share_impl_t impl_share = alloc_share(zfsname, mountpoint);
|
||||
if (impl_share == NULL)
|
||||
return (SA_NO_MEMORY);
|
||||
|
||||
fstype = fstypes;
|
||||
while (fstype != NULL) {
|
||||
if (strcmp(fstype->name, protocol) == 0) {
|
||||
|
||||
rc = fstype->ops->update_shareopts(impl_share,
|
||||
shareopts);
|
||||
if (rc != SA_OK)
|
||||
break;
|
||||
|
||||
rc = fstype->ops->enable_share(impl_share);
|
||||
if (rc != SA_OK)
|
||||
ret = rc;
|
||||
|
||||
found_protocol = B_TRUE;
|
||||
}
|
||||
|
||||
fstype = fstype->next;
|
||||
}
|
||||
free_share(impl_share);
|
||||
|
||||
return (found_protocol ? ret : SA_INVALID_PROTOCOL);
|
||||
const struct sa_share_impl args =
|
||||
init_share(zfsname, mountpoint, shareopts);
|
||||
return (fstype->enable_share(&args));
|
||||
}
|
||||
|
||||
int
|
||||
sa_disable_share(const char *mountpoint, const char *protocol)
|
||||
{
|
||||
int rc, ret = SA_OK;
|
||||
boolean_t found_protocol = B_FALSE;
|
||||
sa_fstype_t *fstype;
|
||||
sa_fstype_t *fstype = find_proto(protocol);
|
||||
if (!fstype)
|
||||
return (SA_INVALID_PROTOCOL);
|
||||
|
||||
sa_share_impl_t impl_share = alloc_share(NULL, mountpoint);
|
||||
if (impl_share == NULL)
|
||||
return (SA_NO_MEMORY);
|
||||
|
||||
fstype = fstypes;
|
||||
while (fstype != NULL) {
|
||||
if (strcmp(fstype->name, protocol) == 0) {
|
||||
|
||||
rc = fstype->ops->disable_share(impl_share);
|
||||
if (rc != SA_OK)
|
||||
ret = rc;
|
||||
|
||||
found_protocol = B_TRUE;
|
||||
}
|
||||
|
||||
fstype = fstype->next;
|
||||
}
|
||||
free_share(impl_share);
|
||||
|
||||
return (found_protocol ? ret : SA_INVALID_PROTOCOL);
|
||||
const struct sa_share_impl args = init_share(NULL, mountpoint, NULL);
|
||||
return (fstype->disable_share(&args));
|
||||
}
|
||||
|
||||
boolean_t
|
||||
sa_is_shared(const char *mountpoint, const char *protocol)
|
||||
{
|
||||
sa_fstype_t *fstype;
|
||||
boolean_t ret = B_FALSE;
|
||||
|
||||
/* guid value is not used */
|
||||
sa_share_impl_t impl_share = alloc_share(NULL, mountpoint);
|
||||
if (impl_share == NULL)
|
||||
sa_fstype_t *fstype = find_proto(protocol);
|
||||
if (!fstype)
|
||||
return (B_FALSE);
|
||||
|
||||
fstype = fstypes;
|
||||
while (fstype != NULL) {
|
||||
if (strcmp(fstype->name, protocol) == 0) {
|
||||
ret = fstype->ops->is_shared(impl_share);
|
||||
}
|
||||
fstype = fstype->next;
|
||||
}
|
||||
free_share(impl_share);
|
||||
return (ret);
|
||||
const struct sa_share_impl args = init_share(NULL, mountpoint, NULL);
|
||||
return (fstype->is_shared(&args));
|
||||
}
|
||||
|
||||
void
|
||||
sa_commit_shares(const char *protocol)
|
||||
{
|
||||
sa_fstype_t *fstype = fstypes;
|
||||
while (fstype != NULL) {
|
||||
if (strcmp(fstype->name, protocol) == 0)
|
||||
fstype->ops->commit_shares();
|
||||
fstype = fstype->next;
|
||||
}
|
||||
sa_fstype_t *fstype = find_proto(protocol);
|
||||
if (!fstype)
|
||||
return;
|
||||
|
||||
fstype->commit_shares();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -181,185 +127,91 @@ const char *
|
||||
sa_errorstr(int err)
|
||||
{
|
||||
static char errstr[32];
|
||||
char *ret = NULL;
|
||||
|
||||
switch (err) {
|
||||
case SA_OK:
|
||||
ret = dgettext(TEXT_DOMAIN, "ok");
|
||||
break;
|
||||
return (dgettext(TEXT_DOMAIN, "ok"));
|
||||
case SA_NO_SUCH_PATH:
|
||||
ret = dgettext(TEXT_DOMAIN, "path doesn't exist");
|
||||
break;
|
||||
return (dgettext(TEXT_DOMAIN, "path doesn't exist"));
|
||||
case SA_NO_MEMORY:
|
||||
ret = dgettext(TEXT_DOMAIN, "no memory");
|
||||
break;
|
||||
return (dgettext(TEXT_DOMAIN, "no memory"));
|
||||
case SA_DUPLICATE_NAME:
|
||||
ret = dgettext(TEXT_DOMAIN, "name in use");
|
||||
break;
|
||||
return (dgettext(TEXT_DOMAIN, "name in use"));
|
||||
case SA_BAD_PATH:
|
||||
ret = dgettext(TEXT_DOMAIN, "bad path");
|
||||
break;
|
||||
return (dgettext(TEXT_DOMAIN, "bad path"));
|
||||
case SA_NO_SUCH_GROUP:
|
||||
ret = dgettext(TEXT_DOMAIN, "no such group");
|
||||
break;
|
||||
return (dgettext(TEXT_DOMAIN, "no such group"));
|
||||
case SA_CONFIG_ERR:
|
||||
ret = dgettext(TEXT_DOMAIN, "configuration error");
|
||||
break;
|
||||
return (dgettext(TEXT_DOMAIN, "configuration error"));
|
||||
case SA_SYSTEM_ERR:
|
||||
ret = dgettext(TEXT_DOMAIN, "system error");
|
||||
break;
|
||||
return (dgettext(TEXT_DOMAIN, "system error"));
|
||||
case SA_SYNTAX_ERR:
|
||||
ret = dgettext(TEXT_DOMAIN, "syntax error");
|
||||
break;
|
||||
return (dgettext(TEXT_DOMAIN, "syntax error"));
|
||||
case SA_NO_PERMISSION:
|
||||
ret = dgettext(TEXT_DOMAIN, "no permission");
|
||||
break;
|
||||
return (dgettext(TEXT_DOMAIN, "no permission"));
|
||||
case SA_BUSY:
|
||||
ret = dgettext(TEXT_DOMAIN, "busy");
|
||||
break;
|
||||
return (dgettext(TEXT_DOMAIN, "busy"));
|
||||
case SA_NO_SUCH_PROP:
|
||||
ret = dgettext(TEXT_DOMAIN, "no such property");
|
||||
break;
|
||||
return (dgettext(TEXT_DOMAIN, "no such property"));
|
||||
case SA_INVALID_NAME:
|
||||
ret = dgettext(TEXT_DOMAIN, "invalid name");
|
||||
break;
|
||||
return (dgettext(TEXT_DOMAIN, "invalid name"));
|
||||
case SA_INVALID_PROTOCOL:
|
||||
ret = dgettext(TEXT_DOMAIN, "invalid protocol");
|
||||
break;
|
||||
return (dgettext(TEXT_DOMAIN, "invalid protocol"));
|
||||
case SA_NOT_ALLOWED:
|
||||
ret = dgettext(TEXT_DOMAIN, "operation not allowed");
|
||||
break;
|
||||
return (dgettext(TEXT_DOMAIN, "operation not allowed"));
|
||||
case SA_BAD_VALUE:
|
||||
ret = dgettext(TEXT_DOMAIN, "bad property value");
|
||||
break;
|
||||
return (dgettext(TEXT_DOMAIN, "bad property value"));
|
||||
case SA_INVALID_SECURITY:
|
||||
ret = dgettext(TEXT_DOMAIN, "invalid security type");
|
||||
break;
|
||||
return (dgettext(TEXT_DOMAIN, "invalid security type"));
|
||||
case SA_NO_SUCH_SECURITY:
|
||||
ret = dgettext(TEXT_DOMAIN, "security type not found");
|
||||
break;
|
||||
return (dgettext(TEXT_DOMAIN, "security type not found"));
|
||||
case SA_VALUE_CONFLICT:
|
||||
ret = dgettext(TEXT_DOMAIN, "property value conflict");
|
||||
break;
|
||||
return (dgettext(TEXT_DOMAIN, "property value conflict"));
|
||||
case SA_NOT_IMPLEMENTED:
|
||||
ret = dgettext(TEXT_DOMAIN, "not implemented");
|
||||
break;
|
||||
return (dgettext(TEXT_DOMAIN, "not implemented"));
|
||||
case SA_INVALID_PATH:
|
||||
ret = dgettext(TEXT_DOMAIN, "invalid path");
|
||||
break;
|
||||
return (dgettext(TEXT_DOMAIN, "invalid path"));
|
||||
case SA_NOT_SUPPORTED:
|
||||
ret = dgettext(TEXT_DOMAIN, "operation not supported");
|
||||
break;
|
||||
return (dgettext(TEXT_DOMAIN, "operation not supported"));
|
||||
case SA_PROP_SHARE_ONLY:
|
||||
ret = dgettext(TEXT_DOMAIN, "property not valid for group");
|
||||
break;
|
||||
return (dgettext(TEXT_DOMAIN, "property not valid for group"));
|
||||
case SA_NOT_SHARED:
|
||||
ret = dgettext(TEXT_DOMAIN, "not shared");
|
||||
break;
|
||||
return (dgettext(TEXT_DOMAIN, "not shared"));
|
||||
case SA_NO_SUCH_RESOURCE:
|
||||
ret = dgettext(TEXT_DOMAIN, "no such resource");
|
||||
break;
|
||||
return (dgettext(TEXT_DOMAIN, "no such resource"));
|
||||
case SA_RESOURCE_REQUIRED:
|
||||
ret = dgettext(TEXT_DOMAIN, "resource name required");
|
||||
break;
|
||||
return (dgettext(TEXT_DOMAIN, "resource name required"));
|
||||
case SA_MULTIPLE_ERROR:
|
||||
ret = dgettext(TEXT_DOMAIN, "errors from multiple protocols");
|
||||
break;
|
||||
return (dgettext(TEXT_DOMAIN,
|
||||
"errors from multiple protocols"));
|
||||
case SA_PATH_IS_SUBDIR:
|
||||
ret = dgettext(TEXT_DOMAIN, "path is a subpath of share");
|
||||
break;
|
||||
return (dgettext(TEXT_DOMAIN, "path is a subpath of share"));
|
||||
case SA_PATH_IS_PARENTDIR:
|
||||
ret = dgettext(TEXT_DOMAIN, "path is parent of a share");
|
||||
break;
|
||||
return (dgettext(TEXT_DOMAIN, "path is parent of a share"));
|
||||
case SA_NO_SECTION:
|
||||
ret = dgettext(TEXT_DOMAIN, "protocol requires a section");
|
||||
break;
|
||||
return (dgettext(TEXT_DOMAIN, "protocol requires a section"));
|
||||
case SA_NO_PROPERTIES:
|
||||
ret = dgettext(TEXT_DOMAIN, "properties not found");
|
||||
break;
|
||||
return (dgettext(TEXT_DOMAIN, "properties not found"));
|
||||
case SA_NO_SUCH_SECTION:
|
||||
ret = dgettext(TEXT_DOMAIN, "section not found");
|
||||
break;
|
||||
return (dgettext(TEXT_DOMAIN, "section not found"));
|
||||
case SA_PASSWORD_ENC:
|
||||
ret = dgettext(TEXT_DOMAIN, "passwords must be encrypted");
|
||||
break;
|
||||
return (dgettext(TEXT_DOMAIN, "passwords must be encrypted"));
|
||||
case SA_SHARE_EXISTS:
|
||||
ret = dgettext(TEXT_DOMAIN, "path or file is already shared");
|
||||
break;
|
||||
return (dgettext(TEXT_DOMAIN,
|
||||
"path or file is already shared"));
|
||||
default:
|
||||
(void) snprintf(errstr, sizeof (errstr),
|
||||
dgettext(TEXT_DOMAIN, "unknown %d"), err);
|
||||
ret = errstr;
|
||||
return (errstr);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
sa_validate_shareopts(const char *options, const char *proto)
|
||||
sa_validate_shareopts(const char *options, const char *protocol)
|
||||
{
|
||||
sa_fstype_t *fstype;
|
||||
sa_fstype_t *fstype = find_proto(protocol);
|
||||
if (!fstype)
|
||||
return (SA_INVALID_PROTOCOL);
|
||||
|
||||
fstype = fstypes;
|
||||
while (fstype != NULL) {
|
||||
if (strcmp(fstype->name, proto) != 0) {
|
||||
fstype = fstype->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
return (fstype->ops->validate_shareopts(options));
|
||||
}
|
||||
|
||||
return (SA_INVALID_PROTOCOL);
|
||||
}
|
||||
|
||||
static sa_share_impl_t
|
||||
alloc_share(const char *zfsname, const char *mountpoint)
|
||||
{
|
||||
sa_share_impl_t impl_share;
|
||||
|
||||
impl_share = calloc(1, sizeof (struct sa_share_impl));
|
||||
|
||||
if (impl_share == NULL)
|
||||
return (NULL);
|
||||
|
||||
if (mountpoint != NULL &&
|
||||
((impl_share->sa_mountpoint = strdup(mountpoint)) == NULL)) {
|
||||
free(impl_share);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (zfsname != NULL &&
|
||||
((impl_share->sa_zfsname = strdup(zfsname)) == NULL)) {
|
||||
free(impl_share->sa_mountpoint);
|
||||
free(impl_share);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
impl_share->sa_fsinfo = calloc(fstypes_count,
|
||||
sizeof (sa_share_fsinfo_t));
|
||||
if (impl_share->sa_fsinfo == NULL) {
|
||||
free(impl_share->sa_mountpoint);
|
||||
free(impl_share->sa_zfsname);
|
||||
free(impl_share);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
return (impl_share);
|
||||
}
|
||||
|
||||
static void
|
||||
free_share(sa_share_impl_t impl_share)
|
||||
{
|
||||
sa_fstype_t *fstype;
|
||||
|
||||
fstype = fstypes;
|
||||
while (fstype != NULL) {
|
||||
fstype->ops->clear_shareopts(impl_share);
|
||||
fstype = fstype->next;
|
||||
}
|
||||
|
||||
free(impl_share->sa_mountpoint);
|
||||
free(impl_share->sa_zfsname);
|
||||
free(impl_share->sa_fsinfo);
|
||||
free(impl_share);
|
||||
return (fstype->validate_shareopts(options));
|
||||
}
|
||||
|
@ -27,39 +27,26 @@
|
||||
#ifndef _LIBSPL_LIBSHARE_IMPL_H
|
||||
#define _LIBSPL_LIBSHARE_IMPL_H
|
||||
|
||||
typedef struct sa_share_fsinfo {
|
||||
char *shareopts;
|
||||
} sa_share_fsinfo_t;
|
||||
#include <sys/avl.h>
|
||||
|
||||
typedef struct sa_share_impl {
|
||||
char *sa_mountpoint;
|
||||
char *sa_zfsname;
|
||||
|
||||
sa_share_fsinfo_t *sa_fsinfo; /* per-fstype information */
|
||||
typedef const struct sa_share_impl {
|
||||
const char *sa_zfsname;
|
||||
const char *sa_mountpoint;
|
||||
const char *sa_shareopts;
|
||||
} *sa_share_impl_t;
|
||||
|
||||
#define FSINFO(impl_share, fstype) \
|
||||
(&(impl_share->sa_fsinfo[fstype->fsinfo_index]))
|
||||
typedef struct {
|
||||
const char *protocol;
|
||||
|
||||
typedef struct sa_share_ops {
|
||||
int (*enable_share)(sa_share_impl_t share);
|
||||
int (*disable_share)(sa_share_impl_t share);
|
||||
boolean_t (*is_shared)(sa_share_impl_t share);
|
||||
int (*validate_shareopts)(const char *shareopts);
|
||||
int (*update_shareopts)(sa_share_impl_t impl_share,
|
||||
const char *shareopts);
|
||||
void (*clear_shareopts)(sa_share_impl_t impl_share);
|
||||
int (*commit_shares)(void);
|
||||
} sa_share_ops_t;
|
||||
int (*const enable_share)(sa_share_impl_t share);
|
||||
int (*const disable_share)(sa_share_impl_t share);
|
||||
boolean_t (*const is_shared)(sa_share_impl_t share);
|
||||
int (*const validate_shareopts)(const char *shareopts);
|
||||
int (*const commit_shares)(void);
|
||||
|
||||
typedef struct sa_fstype {
|
||||
struct sa_fstype *next;
|
||||
|
||||
const char *name;
|
||||
const sa_share_ops_t *ops;
|
||||
int fsinfo_index;
|
||||
avl_node_t node;
|
||||
} sa_fstype_t;
|
||||
|
||||
sa_fstype_t *register_fstype(const char *name, const sa_share_ops_t *ops);
|
||||
extern sa_fstype_t libshare_nfs_type, libshare_smb_type;
|
||||
|
||||
#endif /* _LIBSPL_LIBSHARE_IMPL_H */
|
||||
|
@ -28,8 +28,6 @@
|
||||
|
||||
#define FILE_HEADER "# !!! DO NOT EDIT THIS FILE MANUALLY !!!\n\n"
|
||||
|
||||
void libshare_nfs_init(void);
|
||||
|
||||
boolean_t nfs_is_shared_impl(const char *exports, sa_share_impl_t impl_share);
|
||||
int nfs_toggle_share(const char *lockfile, const char *exports,
|
||||
const char *expdir, sa_share_impl_t impl_share,
|
||||
|
@ -52,8 +52,6 @@ __FBSDID("$FreeBSD$");
|
||||
#define ZFS_EXPORTS_FILE "/etc/zfs/exports"
|
||||
#define ZFS_EXPORTS_LOCK ZFS_EXPORTS_FILE".lock"
|
||||
|
||||
static sa_fstype_t *nfs_fstype;
|
||||
|
||||
/*
|
||||
* This function translates options to a format acceptable by exports(5), eg.
|
||||
*
|
||||
@ -107,7 +105,7 @@ translate_opts(const char *shareopts, FILE *out)
|
||||
static int
|
||||
nfs_enable_share_impl(sa_share_impl_t impl_share, FILE *tmpfile)
|
||||
{
|
||||
char *shareopts = FSINFO(impl_share, nfs_fstype)->shareopts;
|
||||
const char *shareopts = impl_share->sa_shareopts;
|
||||
if (strcmp(shareopts, "on") == 0)
|
||||
shareopts = "";
|
||||
|
||||
@ -158,19 +156,6 @@ nfs_validate_shareopts(const char *shareopts)
|
||||
return (SA_OK);
|
||||
}
|
||||
|
||||
static int
|
||||
nfs_update_shareopts(sa_share_impl_t impl_share, const char *shareopts)
|
||||
{
|
||||
FSINFO(impl_share, nfs_fstype)->shareopts = (char *)shareopts;
|
||||
return (SA_OK);
|
||||
}
|
||||
|
||||
static void
|
||||
nfs_clear_shareopts(sa_share_impl_t impl_share)
|
||||
{
|
||||
FSINFO(impl_share, nfs_fstype)->shareopts = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Commit the shares by restarting mountd.
|
||||
*/
|
||||
@ -201,22 +186,13 @@ nfs_commit_shares(void)
|
||||
return (SA_OK);
|
||||
}
|
||||
|
||||
static const sa_share_ops_t nfs_shareops = {
|
||||
sa_fstype_t libshare_nfs_type = {
|
||||
.protocol = "nfs",
|
||||
|
||||
.enable_share = nfs_enable_share,
|
||||
.disable_share = nfs_disable_share,
|
||||
.is_shared = nfs_is_shared,
|
||||
|
||||
.validate_shareopts = nfs_validate_shareopts,
|
||||
.update_shareopts = nfs_update_shareopts,
|
||||
.clear_shareopts = nfs_clear_shareopts,
|
||||
.commit_shares = nfs_commit_shares,
|
||||
};
|
||||
|
||||
/*
|
||||
* Initializes the NFS functionality of libshare.
|
||||
*/
|
||||
void
|
||||
libshare_nfs_init(void)
|
||||
{
|
||||
nfs_fstype = register_fstype("nfs", &nfs_shareops);
|
||||
}
|
||||
|
@ -27,8 +27,6 @@
|
||||
#include <libshare.h>
|
||||
#include "libshare_impl.h"
|
||||
|
||||
static sa_fstype_t *smb_fstype;
|
||||
|
||||
/*
|
||||
* Enables SMB sharing for the specified share.
|
||||
*/
|
||||
@ -71,51 +69,20 @@ smb_is_share_active(sa_share_impl_t impl_share)
|
||||
return (B_FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called to update a share's options. A share's options might be out of
|
||||
* date if the share was loaded from disk and the "sharesmb" dataset
|
||||
* property has changed in the meantime. This function also takes care
|
||||
* of re-enabling the share if necessary.
|
||||
*/
|
||||
static int
|
||||
smb_update_shareopts(sa_share_impl_t impl_share, const char *shareopts)
|
||||
{
|
||||
(void) impl_share, (void) shareopts;
|
||||
return (SA_OK);
|
||||
}
|
||||
|
||||
static int
|
||||
smb_update_shares(void)
|
||||
{
|
||||
/* Not implemented */
|
||||
return (0);
|
||||
}
|
||||
/*
|
||||
* Clears a share's SMB options. Used by libshare to
|
||||
* clean up shares that are about to be free()'d.
|
||||
*/
|
||||
static void
|
||||
smb_clear_shareopts(sa_share_impl_t impl_share)
|
||||
{
|
||||
FSINFO(impl_share, smb_fstype)->shareopts = NULL;
|
||||
}
|
||||
|
||||
static const sa_share_ops_t smb_shareops = {
|
||||
sa_fstype_t libshare_smb_type = {
|
||||
.protocol = "smb",
|
||||
|
||||
.enable_share = smb_enable_share,
|
||||
.disable_share = smb_disable_share,
|
||||
.is_shared = smb_is_share_active,
|
||||
|
||||
.validate_shareopts = smb_validate_shareopts,
|
||||
.update_shareopts = smb_update_shareopts,
|
||||
.clear_shareopts = smb_clear_shareopts,
|
||||
.commit_shares = smb_update_shares,
|
||||
};
|
||||
|
||||
/*
|
||||
* Initializes the SMB functionality of libshare.
|
||||
*/
|
||||
void
|
||||
libshare_smb_init(void)
|
||||
{
|
||||
smb_fstype = register_fstype("smb", &smb_shareops);
|
||||
}
|
||||
|
@ -45,8 +45,6 @@
|
||||
#define ZFS_EXPORTS_FILE ZFS_EXPORTS_DIR"/zfs.exports"
|
||||
#define ZFS_EXPORTS_LOCK ZFS_EXPORTS_FILE".lock"
|
||||
|
||||
static sa_fstype_t *nfs_fstype;
|
||||
|
||||
typedef int (*nfs_shareopt_callback_t)(const char *opt, const char *value,
|
||||
void *cookie);
|
||||
|
||||
@ -229,7 +227,6 @@ foreach_nfs_host(sa_share_impl_t impl_share, FILE *tmpfile,
|
||||
nfs_host_callback_t callback, void *cookie)
|
||||
{
|
||||
nfs_host_cookie_t udata;
|
||||
char *shareopts;
|
||||
|
||||
udata.callback = callback;
|
||||
udata.sharepath = impl_share->sa_mountpoint;
|
||||
@ -237,10 +234,8 @@ foreach_nfs_host(sa_share_impl_t impl_share, FILE *tmpfile,
|
||||
udata.tmpfile = tmpfile;
|
||||
udata.security = "sys";
|
||||
|
||||
shareopts = FSINFO(impl_share, nfs_fstype)->shareopts;
|
||||
|
||||
return (foreach_nfs_shareopt(shareopts, foreach_nfs_host_cb,
|
||||
&udata));
|
||||
return (foreach_nfs_shareopt(impl_share->sa_shareopts,
|
||||
foreach_nfs_host_cb, &udata));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -411,11 +406,10 @@ nfs_add_entry(FILE *tmpfile, const char *sharepath,
|
||||
static int
|
||||
nfs_enable_share_impl(sa_share_impl_t impl_share, FILE *tmpfile)
|
||||
{
|
||||
char *shareopts, *linux_opts;
|
||||
char *linux_opts;
|
||||
int error;
|
||||
|
||||
shareopts = FSINFO(impl_share, nfs_fstype)->shareopts;
|
||||
error = get_linux_shareopts(shareopts, &linux_opts);
|
||||
error = get_linux_shareopts(impl_share->sa_shareopts, &linux_opts);
|
||||
if (error != SA_OK)
|
||||
return (error);
|
||||
|
||||
@ -475,23 +469,6 @@ nfs_validate_shareopts(const char *shareopts)
|
||||
return (SA_OK);
|
||||
}
|
||||
|
||||
static int
|
||||
nfs_update_shareopts(sa_share_impl_t impl_share, const char *shareopts)
|
||||
{
|
||||
FSINFO(impl_share, nfs_fstype)->shareopts = (char *)shareopts;
|
||||
return (SA_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clears a share's NFS options. Used by libshare to
|
||||
* clean up shares that are about to be free()'d.
|
||||
*/
|
||||
static void
|
||||
nfs_clear_shareopts(sa_share_impl_t impl_share)
|
||||
{
|
||||
FSINFO(impl_share, nfs_fstype)->shareopts = NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
nfs_commit_shares(void)
|
||||
{
|
||||
@ -504,22 +481,13 @@ nfs_commit_shares(void)
|
||||
return (libzfs_run_process(argv[0], argv, 0));
|
||||
}
|
||||
|
||||
static const sa_share_ops_t nfs_shareops = {
|
||||
sa_fstype_t libshare_nfs_type = {
|
||||
.protocol = "nfs",
|
||||
|
||||
.enable_share = nfs_enable_share,
|
||||
.disable_share = nfs_disable_share,
|
||||
.is_shared = nfs_is_shared,
|
||||
|
||||
.validate_shareopts = nfs_validate_shareopts,
|
||||
.update_shareopts = nfs_update_shareopts,
|
||||
.clear_shareopts = nfs_clear_shareopts,
|
||||
.commit_shares = nfs_commit_shares,
|
||||
};
|
||||
|
||||
/*
|
||||
* Initializes the NFS functionality of libshare.
|
||||
*/
|
||||
void
|
||||
libshare_nfs_init(void)
|
||||
{
|
||||
nfs_fstype = register_fstype("nfs", &nfs_shareops);
|
||||
}
|
||||
|
@ -63,8 +63,6 @@
|
||||
|
||||
static boolean_t smb_available(void);
|
||||
|
||||
static sa_fstype_t *smb_fstype;
|
||||
|
||||
static smb_share_t *smb_shares;
|
||||
static int smb_disable_share(sa_share_impl_t impl_share);
|
||||
static boolean_t smb_is_share_active(sa_share_impl_t impl_share);
|
||||
@ -265,19 +263,16 @@ smb_enable_share_one(const char *sharename, const char *sharepath)
|
||||
static int
|
||||
smb_enable_share(sa_share_impl_t impl_share)
|
||||
{
|
||||
char *shareopts;
|
||||
|
||||
if (!smb_available())
|
||||
return (SA_SYSTEM_ERR);
|
||||
|
||||
if (smb_is_share_active(impl_share))
|
||||
smb_disable_share(impl_share);
|
||||
|
||||
shareopts = FSINFO(impl_share, smb_fstype)->shareopts;
|
||||
if (shareopts == NULL) /* on/off */
|
||||
if (impl_share->sa_shareopts == NULL) /* on/off */
|
||||
return (SA_SYSTEM_ERR);
|
||||
|
||||
if (strcmp(shareopts, "off") == 0)
|
||||
if (strcmp(impl_share->sa_shareopts, "off") == 0)
|
||||
return (SA_OK);
|
||||
|
||||
/* Magic: Enable (i.e., 'create new') share */
|
||||
@ -361,22 +356,6 @@ smb_is_share_active(sa_share_impl_t impl_share)
|
||||
return (B_FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called to update a share's options. A share's options might be out of
|
||||
* date if the share was loaded from disk and the "sharesmb" dataset
|
||||
* property has changed in the meantime. This function also takes care
|
||||
* of re-enabling the share if necessary.
|
||||
*/
|
||||
static int
|
||||
smb_update_shareopts(sa_share_impl_t impl_share, const char *shareopts)
|
||||
{
|
||||
if (!impl_share)
|
||||
return (SA_SYSTEM_ERR);
|
||||
|
||||
FSINFO(impl_share, smb_fstype)->shareopts = (char *)shareopts;
|
||||
return (SA_OK);
|
||||
}
|
||||
|
||||
static int
|
||||
smb_update_shares(void)
|
||||
{
|
||||
@ -384,24 +363,14 @@ smb_update_shares(void)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clears a share's SMB options. Used by libshare to
|
||||
* clean up shares that are about to be free()'d.
|
||||
*/
|
||||
static void
|
||||
smb_clear_shareopts(sa_share_impl_t impl_share)
|
||||
{
|
||||
FSINFO(impl_share, smb_fstype)->shareopts = NULL;
|
||||
}
|
||||
sa_fstype_t libshare_smb_type = {
|
||||
.protocol = "smb",
|
||||
|
||||
static const sa_share_ops_t smb_shareops = {
|
||||
.enable_share = smb_enable_share,
|
||||
.disable_share = smb_disable_share,
|
||||
.is_shared = smb_is_share_active,
|
||||
|
||||
.validate_shareopts = smb_validate_shareopts,
|
||||
.update_shareopts = smb_update_shareopts,
|
||||
.clear_shareopts = smb_clear_shareopts,
|
||||
.commit_shares = smb_update_shares,
|
||||
};
|
||||
|
||||
@ -422,12 +391,3 @@ smb_available(void)
|
||||
|
||||
return (B_TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initializes the SMB functionality of libshare.
|
||||
*/
|
||||
void
|
||||
libshare_smb_init(void)
|
||||
{
|
||||
smb_fstype = register_fstype("smb", &smb_shareops);
|
||||
}
|
||||
|
@ -43,5 +43,3 @@ typedef struct smb_share_s {
|
||||
|
||||
struct smb_share_s *next;
|
||||
} smb_share_t;
|
||||
|
||||
void libshare_smb_init(void);
|
||||
|
Loading…
Reference in New Issue
Block a user