diff options
Diffstat (limited to 'usr/src/lib/libshare/common')
-rw-r--r-- | usr/src/lib/libshare/common/libshare.c | 49 | ||||
-rw-r--r-- | usr/src/lib/libshare/common/libshare.h | 5 | ||||
-rw-r--r-- | usr/src/lib/libshare/common/libshare_zfs.c | 138 | ||||
-rw-r--r-- | usr/src/lib/libshare/common/libsharecore.c | 10 | ||||
-rw-r--r-- | usr/src/lib/libshare/common/mapfile-vers | 4 |
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: *; }; |