diff options
| author | dougm <none@none> | 2007-05-07 16:12:42 -0700 |
|---|---|---|
| committer | dougm <none@none> | 2007-05-07 16:12:42 -0700 |
| commit | 6733190958bbcc0bd6d1d601e7ae0a6994dafb45 (patch) | |
| tree | 10f31ce7e31ce61f8bdc6b0b454cf9865af6792e /usr/src/lib/libshare | |
| parent | afc7d54587eb70585fcc35b5f933cc1ed713d87a (diff) | |
| download | illumos-joyent-6733190958bbcc0bd6d1d601e7ae0a6994dafb45.tar.gz | |
6491973 sharemgr: zfs set sharenfs=on is slow with lots of zfs filesystems
Diffstat (limited to 'usr/src/lib/libshare')
| -rw-r--r-- | usr/src/lib/libshare/common/libshare.h | 4 | ||||
| -rw-r--r-- | usr/src/lib/libshare/common/libshare_zfs.c | 7 | ||||
| -rw-r--r-- | usr/src/lib/libshare/common/libsharecore.c | 93 |
3 files changed, 101 insertions, 3 deletions
diff --git a/usr/src/lib/libshare/common/libshare.h b/usr/src/lib/libshare/common/libshare.h index 81de25f910..754ef61c69 100644 --- a/usr/src/lib/libshare/common/libshare.h +++ b/usr/src/lib/libshare/common/libshare.h @@ -170,8 +170,8 @@ extern sa_optionset_t sa_get_derived_optionset(void *, char *, int); extern void sa_free_derived_optionset(sa_optionset_t); /* property functions */ -extern sa_optionset_t sa_get_property(sa_optionset_t, char *); -extern sa_optionset_t sa_get_next_property(sa_group_t); +extern sa_property_t sa_get_property(sa_optionset_t, char *); +extern sa_property_t sa_get_next_property(sa_group_t); extern char *sa_get_property_attr(sa_property_t, char *); extern sa_property_t sa_create_property(char *, char *); extern int sa_add_property(void *, sa_property_t); diff --git a/usr/src/lib/libshare/common/libshare_zfs.c b/usr/src/lib/libshare/common/libshare_zfs.c index ff4a0ff744..494a516a7f 100644 --- a/usr/src/lib/libshare/common/libshare_zfs.c +++ b/usr/src/lib/libshare/common/libshare_zfs.c @@ -204,6 +204,7 @@ get_zfs_dataset(sa_handle_impl_t impl_handle, char *path) char *dataset = NULL; zfs_handle_t **zlist; char mountpoint[ZFS_MAXPROPLEN]; + char canmount[ZFS_MAXPROPLEN]; get_all_filesystems(impl_handle, &zlist, &count); qsort(zlist, count, sizeof (void *), mountpoint_compare); @@ -221,7 +222,10 @@ get_zfs_dataset(sa_handle_impl_t impl_handle, char *path) continue; /* canmount must be set */ - if (!zfs_prop_get_int(zlist[i], ZFS_PROP_CANMOUNT)) + canmount[0] = '\0'; + if (!zfs_prop_get(zlist[i], ZFS_PROP_CANMOUNT, canmount, + sizeof (canmount), NULL, NULL, 0, B_FALSE) != 0 || + strcmp(canmount, "off") == 0) continue; /* @@ -651,6 +655,7 @@ sa_zfs_set_sharenfs(sa_group_t group, char *path, int on) } impl_handle = (sa_handle_impl_t)sa_find_group_handle(group); + assert(impl_handle != NULL); if (impl_handle != NULL) dataset = get_zfs_dataset(impl_handle, path); else diff --git a/usr/src/lib/libshare/common/libsharecore.c b/usr/src/lib/libshare/common/libsharecore.c index 84a9c9f2ef..8c28d2b54b 100644 --- a/usr/src/lib/libshare/common/libsharecore.c +++ b/usr/src/lib/libshare/common/libsharecore.c @@ -760,6 +760,81 @@ _sa_remove_property(sa_property_t property) } /* + * _sa_create_dummy_share() + * + * Create a share entry suitable for parsing but not tied to any real + * config tree. Need to have a parent as well as the node to parse + * on. Free using _sa_free_dummy_share(share); + */ + +static sa_group_t +_sa_create_dummy_share() +{ + xmlNodePtr parent_node = NULL; + xmlNodePtr child_node = NULL; + + parent_node = xmlNewNode(NULL, (xmlChar *)"group"); + if (parent_node != NULL) { + child_node = xmlNewChild(parent_node, NULL, (xmlChar *)"share", + NULL); + if (child_node != NULL) { + /* + * Use a "zfs" tag since that will make sure nothing + * really attempts to put values into the + * repository. Also ZFS is currently the only user of + * this interface. + */ + set_node_attr(parent_node, "type", "transient"); + set_node_attr(parent_node, "zfs", "true"); + set_node_attr(child_node, "type", "transient"); + set_node_attr(child_node, "zfs", "true"); + } else { + xmlFreeNode(parent_node); + } + } + return (child_node); +} + +/* + * _sa_free_dummy_share(share) + * + * Free the dummy share and its parent. It is an error to try and + * free something that isn't a dummy. + */ + +static int +_sa_free_dummy_share(sa_share_t share) +{ + xmlNodePtr node = (xmlNodePtr)share; + xmlNodePtr parent; + int ret = SA_OK; + char *name; + + if (node != NULL) { + parent = node->parent; + name = (char *)xmlGetProp(node, (xmlChar *)"path"); + if (name != NULL) { + /* Real shares always have a path but a dummy doesn't */ + ret = SA_NOT_ALLOWED; + sa_free_attr_string(name); + } else { + /* + * If there is a parent, do the free on that since + * xmlFreeNode is a recursive function and free's an + * child nodes. + */ + if (parent != NULL) { + node = parent; + } + xmlUnlinkNode(node); + xmlFreeNode(node); + } + } + return (ret); +} + + +/* * sa_parse_legacy_options(group, options, proto) * * In order to support legacy configurations, we allow the protocol @@ -778,10 +853,28 @@ sa_parse_legacy_options(sa_group_t group, char *options, char *proto) { int ret = SA_INVALID_PROTOCOL; sa_group_t parent; + int using_dummy = B_FALSE; + + /* + * if "group" is NULL, this is just a parse without saving + * anything in either SMF or ZFS. Create a dummy group to + * handle this case. + */ + if (group == NULL) { + group = (sa_group_t)_sa_create_dummy_share(); + using_dummy = B_TRUE; + } + parent = sa_get_parent_group(group); if (proto != NULL) ret = sa_proto_legacy_opts(proto, group, options); + + if (using_dummy) { + /* Since this is a dummy parse, cleanup and quit here */ + (void) _sa_free_dummy_share(group); + return (ret); + } /* * if in a group, remove the inherited options and security */ |
