summaryrefslogtreecommitdiff
path: root/usr/src/lib/libshare/common
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libshare/common')
-rw-r--r--usr/src/lib/libshare/common/libshare.c49
-rw-r--r--usr/src/lib/libshare/common/libshare.h5
-rw-r--r--usr/src/lib/libshare/common/libshare_zfs.c138
-rw-r--r--usr/src/lib/libshare/common/libsharecore.c10
-rw-r--r--usr/src/lib/libshare/common/mapfile-vers4
5 files changed, 185 insertions, 21 deletions
diff --git a/usr/src/lib/libshare/common/libshare.c b/usr/src/lib/libshare/common/libshare.c
index 22ad595c6d..30c2c486f1 100644
--- a/usr/src/lib/libshare/common/libshare.c
+++ b/usr/src/lib/libshare/common/libshare.c
@@ -20,8 +20,7 @@
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -99,6 +98,8 @@ struct doc2handle {
sa_handle_impl_t handle;
};
+mutex_t sa_dfstab_lock;
+
/* definitions used in a couple of property functions */
#define SA_PROP_OP_REMOVE 1
#define SA_PROP_OP_ADD 2
@@ -594,18 +595,26 @@ validpath(sa_handle_t handle, char *path, int strictness)
*
* "group" can be either an sa_group_t or an sa_share_t. (void *)
* works since both thse types are also void *.
+ * If the share is a ZFS share, mark it as persistent.
*/
int
sa_is_persistent(void *group)
{
char *type;
int persist = 1;
+ sa_group_t grp;
type = sa_get_group_attr((sa_group_t)group, "type");
- if (type != NULL && strcmp(type, "transient") == 0)
- persist = 0;
- if (type != NULL)
+ if (type != NULL) {
+ if (strcmp(type, "transient") == 0)
+ persist = 0;
sa_free_attr_string(type);
+ }
+
+ grp = (sa_is_share(group)) ? sa_get_parent_group(group) : group;
+ if (sa_group_is_zfs(grp))
+ persist = 1;
+
return (persist);
}
@@ -869,6 +878,7 @@ sa_init(int init_service)
extern int errno;
errno = 0;
(void) lockf(lockfd, F_LOCK, 0);
+ (void) mutex_lock(&sa_dfstab_lock);
/*
* Check whether we are going to need
* to merge any dfstab changes. This
@@ -905,13 +915,15 @@ sa_init(int init_service)
*/
updatelegacy = B_TRUE;
}
- }
- if (updatelegacy == B_FALSE) {
- /* Don't need the lock anymore */
- (void) lockf(lockfd, F_ULOCK, 0);
- (void) close(lockfd);
- }
+ if (updatelegacy == B_FALSE) {
+ (void) mutex_unlock(
+ &sa_dfstab_lock);
+ (void) lockf(lockfd, F_ULOCK,
+ 0);
+ (void) close(lockfd);
+ }
+ }
/*
* It is essential that the document tree and
* the internal list of roots to handles be
@@ -954,6 +966,13 @@ sa_init(int init_service)
* sa_init().
*/
sa_fini(handle);
+ if (updatelegacy == B_TRUE) {
+ (void) mutex_unlock(
+ &sa_dfstab_lock);
+ (void) lockf(lockfd,
+ F_ULOCK, 0);
+ (void) close(lockfd);
+ }
return (NULL);
}
@@ -979,6 +998,7 @@ sa_init(int init_service)
* Safe to unlock now to allow
* others to run
*/
+ (void) mutex_unlock(&sa_dfstab_lock);
(void) lockf(lockfd, F_ULOCK, 0);
(void) close(lockfd);
}
@@ -2502,7 +2522,8 @@ sa_set_share_description(sa_share_t share, char *content)
xmlFreeNode(node);
}
group = sa_get_parent_group(share);
- if (group != NULL && sa_is_persistent(share)) {
+ if (group != NULL &&
+ sa_is_persistent(share) && (!sa_group_is_zfs(group))) {
sa_handle_impl_t impl_handle;
impl_handle = (sa_handle_impl_t)sa_find_group_handle(group);
if (impl_handle != NULL) {
@@ -4335,9 +4356,11 @@ sa_set_resource_description(sa_resource_t resource, char *content)
xmlUnlinkNode(node);
xmlFreeNode(node);
}
+
share = sa_get_resource_parent(resource);
group = sa_get_parent_group(share);
- if (group != NULL && sa_is_persistent(share)) {
+ if (group != NULL &&
+ sa_is_persistent(share) && (!sa_group_is_zfs(group))) {
sa_handle_impl_t impl_handle;
impl_handle = (sa_handle_impl_t)sa_find_group_handle(group);
if (impl_handle != NULL)
diff --git a/usr/src/lib/libshare/common/libshare.h b/usr/src/lib/libshare/common/libshare.h
index e733ea4d10..5d32f60e8f 100644
--- a/usr/src/lib/libshare/common/libshare.h
+++ b/usr/src/lib/libshare/common/libshare.h
@@ -20,8 +20,7 @@
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -36,6 +35,7 @@ extern "C" {
#endif
#include <sys/types.h>
+#include <libnvpair.h>
/*
* Basic datatypes for most functions
@@ -268,6 +268,7 @@ extern int sa_delete_sharetab(sa_handle_t, char *, char *);
extern int sa_zfs_is_shared(sa_handle_t, char *);
extern int sa_group_is_zfs(sa_group_t);
extern int sa_path_is_zfs(char *);
+extern int sa_zfs_setprop(sa_handle_t, char *, nvlist_t *);
/* SA Handle specific functions */
extern sa_handle_t sa_find_group_handle(sa_group_t);
diff --git a/usr/src/lib/libshare/common/libshare_zfs.c b/usr/src/lib/libshare/common/libshare_zfs.c
index 5adef70b4c..b96abc505d 100644
--- a/usr/src/lib/libshare/common/libshare_zfs.c
+++ b/usr/src/lib/libshare/common/libshare_zfs.c
@@ -20,8 +20,7 @@
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#include <stdio.h>
@@ -1446,3 +1445,138 @@ sa_zfs_get_info(libzfs_handle_t *libzfs, char *path, char *mountpointp,
return (ret);
}
+
+/*
+ * This method builds values for "sharesmb" property from the
+ * nvlist argument. The values are returned in sharesmb_val variable.
+ */
+static int
+sa_zfs_sprintf_new_prop(nvlist_t *nvl, char *sharesmb_val)
+{
+ char cur_val[MAXPATHLEN];
+ char *name, *val;
+ nvpair_t *cur;
+ int err = 0;
+
+ cur = nvlist_next_nvpair(nvl, NULL);
+ while (cur != NULL) {
+ name = nvpair_name(cur);
+ err = nvpair_value_string(cur, &val);
+ if ((err != 0) || (name == NULL) || (val == NULL))
+ return (-1);
+
+ (void) snprintf(cur_val, MAXPATHLEN, "%s=%s,", name, val);
+ (void) strlcat(sharesmb_val, cur_val, MAXPATHLEN);
+
+ cur = nvlist_next_nvpair(nvl, cur);
+ }
+
+ return (0);
+}
+
+/*
+ * This method builds values for "sharesmb" property from values
+ * already existing on the share. The properties set via sa_zfs_sprint_new_prop
+ * method are passed in sharesmb_val. If a existing property is already
+ * set via sa_zfs_sprint_new_prop method, then they are not appended
+ * to the sharesmb_val string. The returned sharesmb_val string is a combination
+ * of new and existing values for 'sharesmb' property.
+ */
+static int
+sa_zfs_sprintf_existing_prop(zfs_handle_t *handle, char *sharesmb_val)
+{
+ char shareopts[ZFS_MAXPROPLEN], cur_val[MAXPATHLEN];
+ char *token, *last, *value;
+
+ if (zfs_prop_get(handle, ZFS_PROP_SHARESMB, shareopts,
+ sizeof (shareopts), NULL, NULL, 0, B_FALSE) != 0)
+ return (-1);
+
+ if (strstr(shareopts, "=") == NULL)
+ return (0);
+
+ for (token = strtok_r(shareopts, ",", &last); token != NULL;
+ token = strtok_r(NULL, ",", &last)) {
+ value = strchr(token, '=');
+ if (value == NULL)
+ return (-1);
+ *value++ = '\0';
+
+ (void) snprintf(cur_val, MAXPATHLEN, "%s=", token);
+ if (strstr(sharesmb_val, cur_val) == NULL) {
+ (void) strlcat(cur_val, value, MAXPATHLEN);
+ (void) strlcat(cur_val, ",", MAXPATHLEN);
+ (void) strlcat(sharesmb_val, cur_val, MAXPATHLEN);
+ }
+ }
+
+ return (0);
+}
+
+/*
+ * Sets the share properties on a ZFS share. For now, this method sets only
+ * the "sharesmb" property.
+ *
+ * This method includes building a comma seperated name-value string to be
+ * set on the "sharesmb" property of a ZFS share. This name-value string is
+ * build in 2 steps:
+ * - New property values given as name-value pair are set first.
+ * - Existing optionset properties, which are not part of the new properties
+ * passed in step 1, are appended to the newly set properties.
+ */
+int
+sa_zfs_setprop(sa_handle_t handle, char *path, nvlist_t *nvl)
+{
+ zfs_handle_t *z_fs;
+ libzfs_handle_t *z_lib;
+ char sharesmb_val[MAXPATHLEN];
+ char *dataset, *lastcomma;
+
+ if (nvlist_empty(nvl))
+ return (0);
+
+ if ((handle == NULL) || (path == NULL))
+ return (-1);
+
+ if ((dataset = get_zfs_dataset(handle, path, B_FALSE)) == NULL)
+ return (-1);
+
+ if ((z_lib = libzfs_init()) == NULL) {
+ free(dataset);
+ return (-1);
+ }
+
+ z_fs = zfs_open(z_lib, dataset, ZFS_TYPE_DATASET);
+ if (z_fs == NULL) {
+ free(dataset);
+ libzfs_fini(z_lib);
+ return (-1);
+ }
+
+ bzero(sharesmb_val, MAXPATHLEN);
+ if (sa_zfs_sprintf_new_prop(nvl, sharesmb_val) != 0) {
+ free(dataset);
+ zfs_close(z_fs);
+ libzfs_fini(z_lib);
+ return (-1);
+ }
+
+ if (sa_zfs_sprintf_existing_prop(z_fs, sharesmb_val) != 0) {
+ free(dataset);
+ zfs_close(z_fs);
+ libzfs_fini(z_lib);
+ return (-1);
+ }
+
+ lastcomma = strrchr(sharesmb_val, ',');
+ if ((lastcomma != NULL) && (lastcomma[1] == '\0'))
+ *lastcomma = '\0';
+
+ (void) zfs_prop_set(z_fs, zfs_prop_to_name(ZFS_PROP_SHARESMB),
+ sharesmb_val);
+ free(dataset);
+ zfs_close(z_fs);
+ libzfs_fini(z_lib);
+
+ return (0);
+}
diff --git a/usr/src/lib/libshare/common/libsharecore.c b/usr/src/lib/libshare/common/libsharecore.c
index 18e5f3c793..02b44052ca 100644
--- a/usr/src/lib/libshare/common/libsharecore.c
+++ b/usr/src/lib/libshare/common/libsharecore.c
@@ -20,8 +20,7 @@
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -69,6 +68,7 @@ static char *notice[DFSTAB_NOTICE_LINES] = {
#define MAXARGSFORSHARE 256
static mutex_t sharetab_lock = DEFAULTMUTEX;
+extern mutex_t sa_dfstab_lock;
/* used internally only */
typedef
@@ -545,6 +545,7 @@ sa_comment_line(char *line, char *err)
(void) setvbuf(dfstab, NULL, _IOLBF, BUFSIZ * 8);
sablocksigs(&old);
(void) lockf(fileno(dfstab), F_LOCK, 0);
+ (void) mutex_lock(&sa_dfstab_lock);
list = getdfstab(dfstab);
rewind(dfstab);
/*
@@ -555,6 +556,7 @@ sa_comment_line(char *line, char *err)
outdfstab(dfstab, list);
(void) fprintf(dfstab, "# Error: %s: %s", err, line);
(void) fsync(fileno(dfstab));
+ (void) mutex_unlock(&sa_dfstab_lock);
(void) lockf(fileno(dfstab), F_ULOCK, 0);
(void) fclose(dfstab);
saunblocksigs(&old);
@@ -596,6 +598,7 @@ sa_delete_legacy(sa_share_t share, char *protocol)
parent = sa_get_parent_group(share);
if (parent != NULL) {
(void) lockf(fileno(dfstab), F_LOCK, 0);
+ (void) mutex_lock(&sa_dfstab_lock);
list = getdfstab(dfstab);
rewind(dfstab);
if (protocol != NULL) {
@@ -634,6 +637,7 @@ sa_delete_legacy(sa_share_t share, char *protocol)
if (list != NULL)
dfs_free_list(list);
(void) fflush(dfstab);
+ (void) mutex_unlock(&sa_dfstab_lock);
(void) lockf(fileno(dfstab), F_ULOCK, 0);
}
(void) fsync(fileno(dfstab));
@@ -701,6 +705,7 @@ sa_update_legacy(sa_share_t share, char *proto)
(void) setvbuf(dfstab, NULL, _IOLBF, BUFSIZ * 8);
sablocksigs(&old);
(void) lockf(fileno(dfstab), F_LOCK, 0);
+ (void) mutex_lock(&sa_dfstab_lock);
list = getdfstab(dfstab);
rewind(dfstab);
if (list != NULL)
@@ -708,6 +713,7 @@ sa_update_legacy(sa_share_t share, char *proto)
list = adddfsentry(list, share, proto);
outdfstab(dfstab, list);
(void) fflush(dfstab);
+ (void) mutex_unlock(&sa_dfstab_lock);
(void) lockf(fileno(dfstab), F_ULOCK, 0);
(void) fsync(fileno(dfstab));
saunblocksigs(&old);
diff --git a/usr/src/lib/libshare/common/mapfile-vers b/usr/src/lib/libshare/common/mapfile-vers
index 73c08b1e05..e0b1fa56f7 100644
--- a/usr/src/lib/libshare/common/mapfile-vers
+++ b/usr/src/lib/libshare/common/mapfile-vers
@@ -19,8 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
#
#
@@ -149,6 +148,7 @@ SUNWprivate {
sa_get_zfs_handle;
sa_zfs_process_share;
sa_update_sharetab_ts;
+ sa_zfs_setprop;
local:
*;
};