xref: /onnv-gate/usr/src/lib/libshare/common/plugin.c (revision 8334:5f1c6a3b0fad)
13034Sdougm /*
23034Sdougm  * CDDL HEADER START
33034Sdougm  *
43034Sdougm  * The contents of this file are subject to the terms of the
53034Sdougm  * Common Development and Distribution License (the "License").
63034Sdougm  * You may not use this file except in compliance with the License.
73034Sdougm  *
83034Sdougm  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
93034Sdougm  * or http://www.opensolaris.org/os/licensing.
103034Sdougm  * See the License for the specific language governing permissions
113034Sdougm  * and limitations under the License.
123034Sdougm  *
133034Sdougm  * When distributing Covered Code, include this CDDL HEADER in each
143034Sdougm  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
153034Sdougm  * If applicable, add the following below this CDDL HEADER, with the
163034Sdougm  * fields enclosed by brackets "[]" replaced with your own identifying
173034Sdougm  * information: Portions Copyright [yyyy] [name of copyright owner]
183034Sdougm  *
193034Sdougm  * CDDL HEADER END
203034Sdougm  */
213034Sdougm 
223034Sdougm /*
236007Sthurlow  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
243034Sdougm  * Use is subject to license terms.
253034Sdougm  */
263034Sdougm 
273034Sdougm #include <stdio.h>
283034Sdougm #include <stdlib.h>
293034Sdougm #include <string.h>
303034Sdougm #include <libshare.h>
313034Sdougm #include "libshare_impl.h"
323034Sdougm #include <dlfcn.h>
333034Sdougm #include <link.h>
343034Sdougm #include <sys/types.h>
353034Sdougm #include <sys/param.h>
363034Sdougm #include <sys/stat.h>
373034Sdougm #include <dirent.h>
383034Sdougm #include <libintl.h>
393910Sdougm #include <sys/systeminfo.h>
406304Sdougm #include <thread.h>
416304Sdougm #include <synch.h>
423910Sdougm 
433910Sdougm #define	MAXISALEN	257	/* based on sysinfo(2) man page */
443034Sdougm 
453034Sdougm /*
463034Sdougm  * protocol plugin interface
473034Sdougm  *
483034Sdougm  * finds plugins and makes them accessible. This is only "used" by
493034Sdougm  * libshare.so.
503034Sdougm  */
513034Sdougm 
523034Sdougm struct sa_proto_plugin *sap_proto_list;
533034Sdougm 
543034Sdougm static struct sa_proto_handle sa_proto_handle;
553034Sdougm 
563034Sdougm void proto_plugin_fini();
573034Sdougm 
583034Sdougm /*
59*8334SJose.Borrego@Sun.COM  * Returns true if name is "." or "..", otherwise returns false.
60*8334SJose.Borrego@Sun.COM  */
61*8334SJose.Borrego@Sun.COM static boolean_t
proto_is_dot_or_dotdot(const char * name)62*8334SJose.Borrego@Sun.COM proto_is_dot_or_dotdot(const char *name)
63*8334SJose.Borrego@Sun.COM {
64*8334SJose.Borrego@Sun.COM 	if (*name != '.')
65*8334SJose.Borrego@Sun.COM 		return (B_FALSE);
66*8334SJose.Borrego@Sun.COM 
67*8334SJose.Borrego@Sun.COM 	if ((name[1] == '\0') || (name[1] == '.' && name[2] == '\0'))
68*8334SJose.Borrego@Sun.COM 		return (B_TRUE);
69*8334SJose.Borrego@Sun.COM 
70*8334SJose.Borrego@Sun.COM 	return (B_FALSE);
71*8334SJose.Borrego@Sun.COM }
72*8334SJose.Borrego@Sun.COM 
73*8334SJose.Borrego@Sun.COM /*
743034Sdougm  * proto_plugin_init()
753034Sdougm  *
763034Sdougm  * Initialize the protocol specific plugin modules.
773034Sdougm  *
78*8334SJose.Borrego@Sun.COM  * Walk /usr/lib/fs/\* for libshare_*.so modules, for example,
79*8334SJose.Borrego@Sun.COM  * /usr/lib/fs/nfs/libshare_nfs.so. A protocol specific directory
80*8334SJose.Borrego@Sun.COM  * would have modules with names of the form libshare_<proto>.so.
81*8334SJose.Borrego@Sun.COM  * For each protocol found, initialize it and add it to the internal
82*8334SJose.Borrego@Sun.COM  * list of protocols. These are used for protocol specific operations.
833034Sdougm  */
843034Sdougm 
853034Sdougm int
proto_plugin_init()863034Sdougm proto_plugin_init()
873034Sdougm {
883034Sdougm 	struct sa_proto_plugin *proto;
893034Sdougm 	int num_protos = 0;
903034Sdougm 	struct sa_plugin_ops *plugin_ops;
913034Sdougm 	void *dlhandle;
923034Sdougm 	DIR *dir;
933034Sdougm 	struct dirent *dent;
943034Sdougm 	int ret = SA_OK;
953034Sdougm 	struct stat st;
96*8334SJose.Borrego@Sun.COM 	char isa[MAXISALEN];
973910Sdougm 
983910Sdougm #if defined(_LP64)
99*8334SJose.Borrego@Sun.COM 	if (sysinfo(SI_ARCHITECTURE_64, isa, MAXISALEN) == -1)
100*8334SJose.Borrego@Sun.COM 		isa[0] = '\0';
1013910Sdougm #else
102*8334SJose.Borrego@Sun.COM 	isa[0] = '\0';
1033910Sdougm #endif
104*8334SJose.Borrego@Sun.COM 
105*8334SJose.Borrego@Sun.COM 	if ((dir = opendir(SA_LIB_DIR)) == NULL)
106*8334SJose.Borrego@Sun.COM 		return (SA_OK);
107*8334SJose.Borrego@Sun.COM 
108*8334SJose.Borrego@Sun.COM 	while ((dent = readdir(dir)) != NULL) {
109*8334SJose.Borrego@Sun.COM 		char path[MAXPATHLEN];
110*8334SJose.Borrego@Sun.COM 
111*8334SJose.Borrego@Sun.COM 		if (proto_is_dot_or_dotdot(dent->d_name))
112*8334SJose.Borrego@Sun.COM 			continue;
113*8334SJose.Borrego@Sun.COM 
114*8334SJose.Borrego@Sun.COM 		(void) snprintf(path, MAXPATHLEN,
115*8334SJose.Borrego@Sun.COM 		    "%s/%s/%s/libshare_%s.so.1", SA_LIB_DIR,
116*8334SJose.Borrego@Sun.COM 		    dent->d_name, isa, dent->d_name);
117*8334SJose.Borrego@Sun.COM 
118*8334SJose.Borrego@Sun.COM 		/*
119*8334SJose.Borrego@Sun.COM 		 * If file doesn't exist, don't try to map it
120*8334SJose.Borrego@Sun.COM 		 */
121*8334SJose.Borrego@Sun.COM 		if (stat(path, &st) < 0)
122*8334SJose.Borrego@Sun.COM 			continue;
1234653Sdougm 
124*8334SJose.Borrego@Sun.COM 		if ((dlhandle = dlopen(path, RTLD_FIRST|RTLD_LAZY)) == NULL) {
125*8334SJose.Borrego@Sun.COM 			(void) fprintf(stderr, dgettext(TEXT_DOMAIN,
126*8334SJose.Borrego@Sun.COM 			    "Error in plugin for protocol %s: %s\n"),
127*8334SJose.Borrego@Sun.COM 			    dent->d_name, dlerror());
128*8334SJose.Borrego@Sun.COM 			continue;
129*8334SJose.Borrego@Sun.COM 		}
130*8334SJose.Borrego@Sun.COM 
131*8334SJose.Borrego@Sun.COM 		plugin_ops = (struct sa_plugin_ops *)
132*8334SJose.Borrego@Sun.COM 		    dlsym(dlhandle, "sa_plugin_ops");
133*8334SJose.Borrego@Sun.COM 		if (plugin_ops == NULL) {
134*8334SJose.Borrego@Sun.COM 			(void) fprintf(stderr, dgettext(TEXT_DOMAIN,
135*8334SJose.Borrego@Sun.COM 			    "Error in plugin ops for protocol %s: %s\n"),
136*8334SJose.Borrego@Sun.COM 			    dent->d_name, dlerror());
137*8334SJose.Borrego@Sun.COM 			(void) dlclose(dlhandle);
138*8334SJose.Borrego@Sun.COM 			continue;
1393034Sdougm 		}
140*8334SJose.Borrego@Sun.COM 
141*8334SJose.Borrego@Sun.COM 		proto = (struct sa_proto_plugin *)
142*8334SJose.Borrego@Sun.COM 		    calloc(1, sizeof (struct sa_proto_plugin));
143*8334SJose.Borrego@Sun.COM 		if (proto == NULL) {
144*8334SJose.Borrego@Sun.COM 			(void) dlclose(dlhandle);
145*8334SJose.Borrego@Sun.COM 			ret = SA_NO_MEMORY;
146*8334SJose.Borrego@Sun.COM 			continue;
147*8334SJose.Borrego@Sun.COM 		}
148*8334SJose.Borrego@Sun.COM 
149*8334SJose.Borrego@Sun.COM 		proto->plugin_ops = plugin_ops;
150*8334SJose.Borrego@Sun.COM 		proto->plugin_handle = dlhandle;
151*8334SJose.Borrego@Sun.COM 		num_protos++;
152*8334SJose.Borrego@Sun.COM 		proto->plugin_next = sap_proto_list;
153*8334SJose.Borrego@Sun.COM 		sap_proto_list = proto;
1543034Sdougm 	}
155*8334SJose.Borrego@Sun.COM 
156*8334SJose.Borrego@Sun.COM 	(void) closedir(dir);
157*8334SJose.Borrego@Sun.COM 
158*8334SJose.Borrego@Sun.COM 	if (num_protos != 0) {
1594653Sdougm 		sa_proto_handle.sa_proto =
1604653Sdougm 		    (char **)calloc(num_protos, sizeof (char *));
1614653Sdougm 		sa_proto_handle.sa_ops =
1624653Sdougm 		    (struct sa_plugin_ops **)calloc(num_protos,
1634653Sdougm 		    sizeof (struct sa_plugin_ops *));
1644653Sdougm 		if (sa_proto_handle.sa_proto != NULL &&
1654653Sdougm 		    sa_proto_handle.sa_ops != NULL) {
1664653Sdougm 			int i;
1674653Sdougm 			struct sa_proto_plugin *tmp;
1684653Sdougm 
1694653Sdougm 			for (i = 0, tmp = sap_proto_list;
1706162Sdougm 			    i < num_protos && tmp != NULL;
1714653Sdougm 			    tmp = tmp->plugin_next) {
1726304Sdougm 				int err;
1736304Sdougm 				err = SA_OK;
1744653Sdougm 				if (tmp->plugin_ops->sa_init != NULL)
1754653Sdougm 					err = tmp->plugin_ops->sa_init();
1764653Sdougm 				if (err == SA_OK) {
1774653Sdougm 					/*
1784653Sdougm 					 * Only include if the init
1794653Sdougm 					 * succeeded or was NULL
1804653Sdougm 					 */
1814653Sdougm 					sa_proto_handle.sa_num_proto++;
1824653Sdougm 					sa_proto_handle.sa_ops[i] =
1834653Sdougm 					    tmp->plugin_ops;
1844653Sdougm 					sa_proto_handle.sa_proto[i] =
1854653Sdougm 					    tmp->plugin_ops->sa_protocol;
1864653Sdougm 					i++;
1874653Sdougm 				}
1884653Sdougm 			}
1896304Sdougm 		} else {
1906304Sdougm 			ret = SA_NO_MEMORY;
1913034Sdougm 		}
1926304Sdougm 	}
1936304Sdougm 
1946304Sdougm 	/*
1956304Sdougm 	 * There was an error, so cleanup prior to return of failure.
1966304Sdougm 	 */
1976304Sdougm 	if (ret != SA_OK)
1984653Sdougm 		proto_plugin_fini();
1996304Sdougm 
2003034Sdougm 	return (ret);
2013034Sdougm }
2023034Sdougm 
2033034Sdougm /*
2043034Sdougm  * proto_plugin_fini()
2053034Sdougm  *
2064653Sdougm  * Uninitialize all the plugin modules.
2073034Sdougm  */
2083034Sdougm 
2093034Sdougm void
proto_plugin_fini()2103034Sdougm proto_plugin_fini()
2113034Sdougm {
2127010Sgwr 	struct sa_proto_plugin *p;
2134653Sdougm 
2147010Sgwr 	/*
2157010Sgwr 	 * Protocols may call this framework during _fini
2167010Sgwr 	 * (the smbfs plugin is known to do this) so do
2177010Sgwr 	 * two passes: 1st call _fini; 2nd free, dlclose.
2187010Sgwr 	 */
2197010Sgwr 	for (p = sap_proto_list; p != NULL; p = p->plugin_next)
2207010Sgwr 		p->plugin_ops->sa_fini();
2217010Sgwr 
2227010Sgwr 	while ((p = sap_proto_list) != NULL) {
2237010Sgwr 		sap_proto_list = p->plugin_next;
2247010Sgwr 
2257010Sgwr 		if (p->plugin_handle != NULL)
2267010Sgwr 			(void) dlclose(p->plugin_handle);
2277010Sgwr 		free(p);
2283034Sdougm 	}
2293034Sdougm 	if (sa_proto_handle.sa_ops != NULL) {
2304653Sdougm 		free(sa_proto_handle.sa_ops);
2314653Sdougm 		sa_proto_handle.sa_ops = NULL;
2323034Sdougm 	}
2333034Sdougm 	if (sa_proto_handle.sa_proto != NULL) {
2344653Sdougm 		free(sa_proto_handle.sa_proto);
2354653Sdougm 		sa_proto_handle.sa_proto = NULL;
2363034Sdougm 	}
2373034Sdougm 	sa_proto_handle.sa_num_proto = 0;
2383034Sdougm }
2393034Sdougm 
2403034Sdougm /*
2413034Sdougm  * find_protocol(proto)
2423034Sdougm  *
2433034Sdougm  * Search the plugin list for the specified protocol and return the
2443034Sdougm  * ops vector.  NULL if protocol is not defined.
2453034Sdougm  */
2463034Sdougm 
2473034Sdougm static struct sa_plugin_ops *
find_protocol(char * proto)2483034Sdougm find_protocol(char *proto)
2493034Sdougm {
2503034Sdougm 	int i;
2516304Sdougm 	struct sa_plugin_ops *ops = NULL;
2526304Sdougm 	extern mutex_t sa_global_lock;
2533034Sdougm 
2546304Sdougm 	(void) mutex_lock(&sa_global_lock);
2553034Sdougm 	if (proto != NULL) {
2564653Sdougm 		for (i = 0; i < sa_proto_handle.sa_num_proto; i++) {
2576304Sdougm 			if (strcmp(proto, sa_proto_handle.sa_proto[i]) == 0) {
2586304Sdougm 				ops = sa_proto_handle.sa_ops[i];
2596304Sdougm 				break;
2606304Sdougm 			}
2614653Sdougm 		}
2623034Sdougm 	}
2636304Sdougm 	(void) mutex_unlock(&sa_global_lock);
2646304Sdougm 	return (ops);
2653034Sdougm }
2663034Sdougm 
2673034Sdougm /*
2683034Sdougm  * sa_proto_share(proto, share)
2693034Sdougm  *
2703034Sdougm  * Activate a share for the specified protocol.
2713034Sdougm  */
2723034Sdougm 
2733034Sdougm int
sa_proto_share(char * proto,sa_share_t share)2743034Sdougm sa_proto_share(char *proto, sa_share_t share)
2753034Sdougm {
2763034Sdougm 	struct sa_plugin_ops *ops = find_protocol(proto);
2773034Sdougm 	int ret = SA_INVALID_PROTOCOL;
2783034Sdougm 
2793034Sdougm 	if (ops != NULL && ops->sa_share != NULL)
2804653Sdougm 		ret = ops->sa_share(share);
2813034Sdougm 	return (ret);
2823034Sdougm }
2833034Sdougm 
2843034Sdougm /*
2855331Samw  * sa_proto_unshare(proto, share)
2863034Sdougm  *
2875331Samw  * Deactivate (unshare) the share for this protocol.
2883034Sdougm  */
2893034Sdougm 
2903034Sdougm int
sa_proto_unshare(sa_share_t share,char * proto,char * path)2914543Smarks sa_proto_unshare(sa_share_t share, char *proto, char *path)
2923034Sdougm {
2933034Sdougm 	struct sa_plugin_ops *ops = find_protocol(proto);
2943034Sdougm 	int ret = SA_INVALID_PROTOCOL;
2953034Sdougm 
2963034Sdougm 	if (ops != NULL && ops->sa_unshare != NULL)
2974653Sdougm 		ret = ops->sa_unshare(share, path);
2983034Sdougm 	return (ret);
2993034Sdougm }
3003034Sdougm 
3013034Sdougm /*
3025331Samw  * sa_proto_share_resource(char *proto, sa_resource_t resource)
3035331Samw  *
3045331Samw  * For protocols that actually enable at the resource level, do the
3055331Samw  * protocol specific resource enable. If it doesn't, return an error.
3065331Samw  * Note that the resource functions are optional so can return
3075331Samw  * SA_NOT_SUPPORTED.
3085331Samw  */
3095331Samw 
3105331Samw int
sa_proto_share_resource(char * proto,sa_resource_t resource)3115331Samw sa_proto_share_resource(char *proto, sa_resource_t resource)
3125331Samw {
3135331Samw 	struct sa_plugin_ops *ops = find_protocol(proto);
3145331Samw 	int ret = SA_INVALID_PROTOCOL;
3155331Samw 
3165331Samw 	if (ops != NULL) {
3175331Samw 		if (ops->sa_enable_resource != NULL)
3185331Samw 			ret = ops->sa_enable_resource(resource);
3195331Samw 		else
3205331Samw 			ret = SA_NOT_SUPPORTED;
3215331Samw 	}
3225331Samw 	return (ret);
3235331Samw }
3245331Samw 
3255331Samw /*
3265331Samw  * sa_proto_unshare_resource(char *proto, sa_resource_t resource)
3275331Samw  *
3285331Samw  * For protocols that actually disable at the resource level, do the
3295331Samw  * protocol specific resource disable. If it doesn't, return an error.
3305331Samw  */
3315331Samw 
3325331Samw int
sa_proto_unshare_resource(char * proto,sa_resource_t resource)3335331Samw sa_proto_unshare_resource(char *proto, sa_resource_t resource)
3345331Samw {
3355331Samw 	struct sa_plugin_ops *ops = find_protocol(proto);
3365331Samw 	int ret = SA_INVALID_PROTOCOL;
3375331Samw 
3385331Samw 	if (ops != NULL) {
3395331Samw 		if (ops->sa_disable_resource != NULL)
3405331Samw 			ret = ops->sa_disable_resource(resource);
3415331Samw 		else
3425331Samw 			ret = SA_NOT_SUPPORTED;
3435331Samw 	}
3445331Samw 	return (ret);
3455331Samw }
3465331Samw 
3475331Samw /*
3486214Sdougm  * sa_proto_valid_prop(handle, proto, prop, opt)
3493034Sdougm  *
3504653Sdougm  * Check to see if the specified prop is valid for this protocol.
3513034Sdougm  */
3523034Sdougm 
3533034Sdougm int
sa_proto_valid_prop(sa_handle_t handle,char * proto,sa_property_t prop,sa_optionset_t opt)3546214Sdougm sa_proto_valid_prop(sa_handle_t handle, char *proto, sa_property_t prop,
3556214Sdougm     sa_optionset_t opt)
3563034Sdougm {
3573034Sdougm 	struct sa_plugin_ops *ops = find_protocol(proto);
3583034Sdougm 	int ret = 0;
3593034Sdougm 
3603034Sdougm 	if (ops != NULL && ops->sa_valid_prop != NULL)
3616214Sdougm 		ret = ops->sa_valid_prop(handle, prop, opt);
3623034Sdougm 	return (ret);
3633034Sdougm }
3643034Sdougm 
3653034Sdougm /*
3663034Sdougm  * sa_proto_valid_space(proto, space)
3673034Sdougm  *
3684653Sdougm  * Check if space is valid optionspace for proto.
3693034Sdougm  * Protocols that don't implement this don't support spaces.
3703034Sdougm  */
3713034Sdougm int
sa_proto_valid_space(char * proto,char * token)3723034Sdougm sa_proto_valid_space(char *proto, char *token)
3733034Sdougm {
3743034Sdougm 	struct sa_plugin_ops *ops = find_protocol(proto);
3753034Sdougm 	int ret = 0;
3763034Sdougm 
3773034Sdougm 	if (ops != NULL && ops->sa_valid_space != NULL)
3784653Sdougm 		ret = ops->sa_valid_space(token);
3793034Sdougm 	return (ret);
3803034Sdougm }
3813034Sdougm 
3823034Sdougm /*
3833034Sdougm  * sa_proto_space_alias(proto, space)
3843034Sdougm  *
3854653Sdougm  * If the name for space is an alias, return its proper name.  This is
3863034Sdougm  * used to translate "default" values into proper form.
3873034Sdougm  */
3883034Sdougm char *
sa_proto_space_alias(char * proto,char * space)3893034Sdougm sa_proto_space_alias(char *proto, char *space)
3903034Sdougm {
3913034Sdougm 	struct sa_plugin_ops *ops = find_protocol(proto);
3923034Sdougm 	char *ret = space;
3933034Sdougm 
3943034Sdougm 	if (ops != NULL && ops->sa_space_alias != NULL)
3954653Sdougm 		ret = ops->sa_space_alias(space);
3963034Sdougm 	return (ret);
3973034Sdougm }
3983034Sdougm 
3993034Sdougm /*
4003034Sdougm  * sa_proto_security_prop(proto, token)
4013034Sdougm  *
4023034Sdougm  * Check to see if the property name in token is a valid named
4033034Sdougm  * optionset property.
4043034Sdougm  */
4053034Sdougm 
4063034Sdougm int
sa_proto_security_prop(char * proto,char * token)4073034Sdougm sa_proto_security_prop(char *proto, char *token)
4083034Sdougm {
4093034Sdougm 	struct sa_plugin_ops *ops = find_protocol(proto);
4103034Sdougm 	int ret = 0;
4113034Sdougm 
4123034Sdougm 	if (ops != NULL && ops->sa_security_prop != NULL)
4134653Sdougm 		ret = ops->sa_security_prop(token);
4143034Sdougm 	return (ret);
4153034Sdougm }
4163034Sdougm 
4173034Sdougm /*
4183034Sdougm  * sa_proto_legacy_opts(proto, grouup, options)
4193034Sdougm  *
4203034Sdougm  * Have the protocol specific parser parse the options string and add
4213034Sdougm  * an appropriate optionset to group.
4223034Sdougm  */
4233034Sdougm 
4243034Sdougm int
sa_proto_legacy_opts(char * proto,sa_group_t group,char * options)4253034Sdougm sa_proto_legacy_opts(char *proto, sa_group_t group, char *options)
4263034Sdougm {
4273034Sdougm 	struct sa_plugin_ops *ops = find_protocol(proto);
4283034Sdougm 	int ret = SA_INVALID_PROTOCOL;
4293034Sdougm 
4303034Sdougm 	if (ops != NULL && ops->sa_legacy_opts != NULL)
4314653Sdougm 		ret = ops->sa_legacy_opts(group, options);
4323034Sdougm 	return (ret);
4333034Sdougm }
4343034Sdougm 
4353034Sdougm /*
4363034Sdougm  * sa_proto_legacy_format(proto, group, hier)
4373034Sdougm  *
4383034Sdougm  * Return a legacy format string representing either the group's
4393034Sdougm  * properties or the groups hierarchical properties.
4403034Sdougm  */
4413034Sdougm 
4423034Sdougm char *
sa_proto_legacy_format(char * proto,sa_group_t group,int hier)4433034Sdougm sa_proto_legacy_format(char *proto, sa_group_t group, int hier)
4443034Sdougm {
4453034Sdougm 	struct sa_plugin_ops *ops = find_protocol(proto);
4463034Sdougm 	char *ret = NULL;
4473034Sdougm 
4483034Sdougm 	if (ops != NULL && ops->sa_legacy_format != NULL)
4494653Sdougm 		ret = ops->sa_legacy_format(group, hier);
4503034Sdougm 	return (ret);
4513034Sdougm }
4523034Sdougm 
4533034Sdougm void
sa_format_free(char * str)4543034Sdougm sa_format_free(char *str)
4553034Sdougm {
4563034Sdougm 	free(str);
4573034Sdougm }
4583034Sdougm 
4593034Sdougm /*
4603034Sdougm  * sharectl related API functions
4613034Sdougm  */
4623034Sdougm 
4633034Sdougm /*
4643034Sdougm  * sa_proto_get_properties(proto)
4653034Sdougm  *
4663034Sdougm  * Return the set of properties that are specific to the
4673034Sdougm  * protocol. These are usually in /etc/dfs/<proto> and related files,
4683034Sdougm  * but only the protocol module knows which ones for sure.
4693034Sdougm  */
4703034Sdougm 
4713034Sdougm sa_protocol_properties_t
sa_proto_get_properties(char * proto)4723034Sdougm sa_proto_get_properties(char *proto)
4733034Sdougm {
4743034Sdougm 	struct sa_plugin_ops *ops = find_protocol(proto);
4753034Sdougm 	sa_protocol_properties_t props = NULL;
4763034Sdougm 
4773034Sdougm 	if (ops != NULL && ops->sa_get_proto_set != NULL)
4784653Sdougm 		props = ops->sa_get_proto_set();
4793034Sdougm 	return (props);
4803034Sdougm }
4813034Sdougm 
4823034Sdougm /*
4833034Sdougm  * sa_proto_set_property(proto, prop)
4843034Sdougm  *
4855331Samw  * Update the protocol specific property.
4863034Sdougm  */
4873034Sdougm 
4883034Sdougm int
sa_proto_set_property(char * proto,sa_property_t prop)4893034Sdougm sa_proto_set_property(char *proto, sa_property_t prop)
4903034Sdougm {
4913034Sdougm 	struct sa_plugin_ops *ops = find_protocol(proto);
4923034Sdougm 	int ret = SA_OK;
4934653Sdougm 
4943034Sdougm 	if (ops != NULL && ops->sa_set_proto_prop != NULL)
4954653Sdougm 		ret = ops->sa_set_proto_prop(prop);
4963034Sdougm 	return (ret);
4973034Sdougm }
4983034Sdougm 
4993034Sdougm /*
5003034Sdougm  * sa_valid_protocol(proto)
5013034Sdougm  *
5024653Sdougm  * Check to see if the protocol specified is defined by a
5033034Sdougm  * plugin. Returns true (1) or false (0)
5043034Sdougm  */
5053034Sdougm 
5063034Sdougm int
sa_valid_protocol(char * proto)5073034Sdougm sa_valid_protocol(char *proto)
5083034Sdougm {
5093034Sdougm 	struct sa_plugin_ops *ops = find_protocol(proto);
5103034Sdougm 	return (ops != NULL);
5113034Sdougm }
5123034Sdougm 
5133034Sdougm /*
5143034Sdougm  * Return the current operational status of the protocol
5153034Sdougm  */
5163034Sdougm 
5173034Sdougm char *
sa_get_protocol_status(char * proto)5183034Sdougm sa_get_protocol_status(char *proto)
5193034Sdougm {
5203034Sdougm 	struct sa_plugin_ops *ops = find_protocol(proto);
5213034Sdougm 	char *ret = NULL;
5223034Sdougm 	if (ops != NULL && ops->sa_get_proto_status != NULL)
5234653Sdougm 		ret = ops->sa_get_proto_status(proto);
5243034Sdougm 	return (ret);
5253034Sdougm }
5263034Sdougm 
5273034Sdougm /*
5283034Sdougm  * sa_proto_update_legacy(proto, share)
5293034Sdougm  *
5303034Sdougm  * Update the protocol specific legacy files if necessary for the
5313034Sdougm  * specified share.
5323034Sdougm  */
5333034Sdougm 
5343034Sdougm int
sa_proto_update_legacy(char * proto,sa_share_t share)5353034Sdougm sa_proto_update_legacy(char *proto, sa_share_t share)
5363034Sdougm {
5373034Sdougm 	struct sa_plugin_ops *ops = find_protocol(proto);
5383034Sdougm 	int ret = SA_NOT_IMPLEMENTED;
5393034Sdougm 
5403034Sdougm 	if (ops != NULL) {
5414653Sdougm 		if (ops->sa_update_legacy != NULL)
5424653Sdougm 			ret = ops->sa_update_legacy(share);
5433034Sdougm 	}
5443034Sdougm 	return (ret);
5453034Sdougm }
5463034Sdougm 
5473034Sdougm /*
5483034Sdougm  * sa_delete_legacy(proto, share)
5493034Sdougm  *
5504653Sdougm  * Remove the specified share from the protocol specific legacy files.
5513034Sdougm  */
5523034Sdougm 
5533034Sdougm int
sa_proto_delete_legacy(char * proto,sa_share_t share)5543034Sdougm sa_proto_delete_legacy(char *proto, sa_share_t share)
5553034Sdougm {
5563034Sdougm 	struct sa_plugin_ops *ops = find_protocol(proto);
5575331Samw 	int ret = SA_NOT_IMPLEMENTED;
5583034Sdougm 
5593034Sdougm 	if (ops != NULL) {
5604653Sdougm 		if (ops->sa_delete_legacy != NULL)
5614653Sdougm 			ret = ops->sa_delete_legacy(share);
5626007Sthurlow 	} else {
5636007Sthurlow 		if (proto != NULL)
5646007Sthurlow 			ret = SA_NOT_IMPLEMENTED;
5656007Sthurlow 		else
5666007Sthurlow 			ret = SA_INVALID_PROTOCOL;
5676007Sthurlow 	}
5686007Sthurlow 	return (ret);
5696007Sthurlow }
5706007Sthurlow 
5716007Sthurlow /*
5726007Sthurlow  * sa_proto_delete_section(proto, section)
5736007Sthurlow  *
5746007Sthurlow  * Remove the specified section from the protocol specific legacy files,
5756007Sthurlow  * if supported.
5766007Sthurlow  */
5776007Sthurlow 
5786007Sthurlow int
sa_proto_delete_section(char * proto,char * section)5796007Sthurlow sa_proto_delete_section(char *proto, char *section)
5806007Sthurlow {
5816007Sthurlow 	struct sa_plugin_ops *ops = find_protocol(proto);
5826007Sthurlow 	int ret = SA_OK;
5836007Sthurlow 
5846007Sthurlow 	if (ops != NULL) {
5856007Sthurlow 		if (ops->sa_delete_proto_section != NULL)
5866007Sthurlow 			ret = ops->sa_delete_proto_section(section);
5876007Sthurlow 	} else {
5886007Sthurlow 		if (proto != NULL)
5896007Sthurlow 			ret = SA_NOT_IMPLEMENTED;
5906007Sthurlow 		else
5916007Sthurlow 			ret = SA_INVALID_PROTOCOL;
5925331Samw 	}
5935331Samw 	return (ret);
5945331Samw }
5955331Samw 
5965331Samw /*
5975331Samw  * sa_proto_change_notify(share, char *protocol)
5985331Samw  *
5995331Samw  * Notify the protocol that a change has been made to the share
6005331Samw  */
6015331Samw 
6025331Samw int
sa_proto_change_notify(sa_share_t share,char * proto)6035331Samw sa_proto_change_notify(sa_share_t share, char *proto)
6045331Samw {
6055331Samw 	struct sa_plugin_ops *ops = find_protocol(proto);
6065331Samw 	int ret = SA_NOT_IMPLEMENTED;
6075331Samw 
6085331Samw 	if (ops != NULL) {
6095331Samw 		if (ops->sa_change_notify != NULL)
6105331Samw 			ret = ops->sa_change_notify(share);
6115331Samw 	} else	if (proto == NULL) {
6126007Sthurlow 
6135331Samw 			ret = SA_INVALID_PROTOCOL;
6145331Samw 	}
6155331Samw 	return (ret);
6165331Samw }
6175331Samw 
6185331Samw /*
6195331Samw  * sa_proto_notify_resource(resource, char *protocol)
6205331Samw  *
6215331Samw  * Notify the protocol that a change has been made to the share
6225331Samw  */
6235331Samw 
6245331Samw int
sa_proto_notify_resource(sa_resource_t resource,char * proto)6255331Samw sa_proto_notify_resource(sa_resource_t resource, char *proto)
6265331Samw {
6275331Samw 	struct sa_plugin_ops *ops = find_protocol(proto);
6285331Samw 	int ret = SA_NOT_IMPLEMENTED;
6295331Samw 
6305331Samw 	if (ops != NULL) {
6315331Samw 		if (ops->sa_notify_resource != NULL)
6325331Samw 			ret = ops->sa_notify_resource(resource);
6335331Samw 	} else if (proto == NULL) {
6344653Sdougm 			ret = SA_INVALID_PROTOCOL;
6353034Sdougm 	}
6363034Sdougm 	return (ret);
6373034Sdougm }
6385331Samw 
6395331Samw /*
6405331Samw  * sa_proto_get_featureset(protocol)
6415331Samw  *
6425331Samw  * Get bitmask of defined features of the protocol. These are
6435331Samw  * primarily things like SA_FEATURE_RESOURCE (shares are by resource
6445331Samw  * name rather than path) and other operational features that affect
6455331Samw  * behavior.
6465331Samw  */
6475331Samw 
6485331Samw uint64_t
sa_proto_get_featureset(char * proto)6495331Samw sa_proto_get_featureset(char *proto)
6505331Samw {
6515331Samw 	struct sa_plugin_ops *ops = find_protocol(proto);
6525331Samw 	uint64_t ret = 0;
6535331Samw 
6545331Samw 	if (ops != NULL) {
6555331Samw 		if (ops->sa_features != NULL)
6565331Samw 			ret = ops->sa_features();
6575331Samw 	}
6585331Samw 	/* if not implemented, zero is valid */
6595331Samw 	return (ret);
6605331Samw }
6615331Samw 
6625331Samw /*
6635331Samw  * sa_proto_get_transients(sa_handle_t)
6645331Samw  *
6655331Samw  * Called to get any protocol specific transient shares.  NFS doesn't
6665331Samw  * use this since the info is in sharetab which is processed as a
6675331Samw  * common transient store.
6685331Samw  *
6695331Samw  * The protocol plugin should verify that the share isn't in the
6705331Samw  * repository and then add it as a transient.
6715331Samw  *
6725331Samw  * Not having an entry is not a problem. It returns 0 in that case.
6735331Samw  */
6745331Samw 
6755331Samw int
sa_proto_get_transients(sa_handle_t handle,char * proto)6765331Samw sa_proto_get_transients(sa_handle_t handle, char *proto)
6775331Samw {
6785331Samw 	struct sa_plugin_ops *ops = find_protocol(proto);
6795331Samw 	int ret = 0;
6805331Samw 
6815331Samw 	if (ops != NULL) {
6825331Samw 		if (ops->sa_get_transient_shares != NULL)
6835331Samw 			ret = ops->sa_get_transient_shares(handle);
6845331Samw 	}
6855331Samw 	return (ret);
6865331Samw }
6875331Samw 
6885331Samw /*
6895331Samw  * sa_proto_rename_resource(sa_handle_t, proto, sa_resource_t, newname)
6905331Samw  *
6915331Samw  * Protocols may need to know when a resource has changed names in
6925331Samw  * order to notify clients. This must be done "before" the name in the
6935331Samw  * resource has been changed. Not being implemented is not a problem.
6945331Samw  */
6955331Samw 
6965331Samw int
sa_proto_rename_resource(sa_handle_t handle,char * proto,sa_resource_t resource,char * newname)6975331Samw sa_proto_rename_resource(sa_handle_t handle, char *proto,
6985331Samw     sa_resource_t resource, char *newname)
6995331Samw {
7005331Samw 	struct sa_plugin_ops *ops = find_protocol(proto);
7015331Samw 	int ret = SA_OK;
7025331Samw 
7035331Samw 	if (ops != NULL) {
7045331Samw 		if (ops->sa_rename_resource != NULL)
7055331Samw 			ret = ops->sa_rename_resource(handle, resource,
7065331Samw 			    newname);
7075331Samw 	}
7085331Samw 	return (ret);
7095331Samw }
710