16185db85Sdougm /*
26185db85Sdougm * CDDL HEADER START
36185db85Sdougm *
46185db85Sdougm * The contents of this file are subject to the terms of the
56185db85Sdougm * Common Development and Distribution License (the "License").
66185db85Sdougm * You may not use this file except in compliance with the License.
76185db85Sdougm *
86185db85Sdougm * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
96185db85Sdougm * or http://www.opensolaris.org/os/licensing.
106185db85Sdougm * See the License for the specific language governing permissions
116185db85Sdougm * and limitations under the License.
126185db85Sdougm *
136185db85Sdougm * When distributing Covered Code, include this CDDL HEADER in each
146185db85Sdougm * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
156185db85Sdougm * If applicable, add the following below this CDDL HEADER, with the
166185db85Sdougm * fields enclosed by brackets "[]" replaced with your own identifying
176185db85Sdougm * information: Portions Copyright [yyyy] [name of copyright owner]
186185db85Sdougm *
196185db85Sdougm * CDDL HEADER END
206185db85Sdougm */
216185db85Sdougm
226185db85Sdougm /*
234bff34e3Sthurlow * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
246185db85Sdougm * Use is subject to license terms.
256185db85Sdougm */
266185db85Sdougm
276185db85Sdougm #include <stdio.h>
286185db85Sdougm #include <stdlib.h>
296185db85Sdougm #include <string.h>
306185db85Sdougm #include <libshare.h>
316185db85Sdougm #include "libshare_impl.h"
326185db85Sdougm #include <dlfcn.h>
336185db85Sdougm #include <link.h>
346185db85Sdougm #include <sys/types.h>
356185db85Sdougm #include <sys/param.h>
366185db85Sdougm #include <sys/stat.h>
376185db85Sdougm #include <dirent.h>
386185db85Sdougm #include <libintl.h>
39549ec3ffSdougm #include <sys/systeminfo.h>
40c5f58477Sdougm #include <thread.h>
41c5f58477Sdougm #include <synch.h>
42549ec3ffSdougm
43549ec3ffSdougm #define MAXISALEN 257 /* based on sysinfo(2) man page */
446185db85Sdougm
456185db85Sdougm /*
466185db85Sdougm * protocol plugin interface
476185db85Sdougm *
486185db85Sdougm * finds plugins and makes them accessible. This is only "used" by
496185db85Sdougm * libshare.so.
506185db85Sdougm */
516185db85Sdougm
526185db85Sdougm struct sa_proto_plugin *sap_proto_list;
536185db85Sdougm
546185db85Sdougm static struct sa_proto_handle sa_proto_handle;
556185db85Sdougm
566185db85Sdougm void proto_plugin_fini();
576185db85Sdougm
586185db85Sdougm /*
59*8d7e4166Sjose borrego * Returns true if name is "." or "..", otherwise returns false.
60*8d7e4166Sjose borrego */
61*8d7e4166Sjose borrego static boolean_t
proto_is_dot_or_dotdot(const char * name)62*8d7e4166Sjose borrego proto_is_dot_or_dotdot(const char *name)
63*8d7e4166Sjose borrego {
64*8d7e4166Sjose borrego if (*name != '.')
65*8d7e4166Sjose borrego return (B_FALSE);
66*8d7e4166Sjose borrego
67*8d7e4166Sjose borrego if ((name[1] == '\0') || (name[1] == '.' && name[2] == '\0'))
68*8d7e4166Sjose borrego return (B_TRUE);
69*8d7e4166Sjose borrego
70*8d7e4166Sjose borrego return (B_FALSE);
71*8d7e4166Sjose borrego }
72*8d7e4166Sjose borrego
73*8d7e4166Sjose borrego /*
746185db85Sdougm * proto_plugin_init()
756185db85Sdougm *
766185db85Sdougm * Initialize the protocol specific plugin modules.
776185db85Sdougm *
78*8d7e4166Sjose borrego * Walk /usr/lib/fs/\* for libshare_*.so modules, for example,
79*8d7e4166Sjose borrego * /usr/lib/fs/nfs/libshare_nfs.so. A protocol specific directory
80*8d7e4166Sjose borrego * would have modules with names of the form libshare_<proto>.so.
81*8d7e4166Sjose borrego * For each protocol found, initialize it and add it to the internal
82*8d7e4166Sjose borrego * list of protocols. These are used for protocol specific operations.
836185db85Sdougm */
846185db85Sdougm
856185db85Sdougm int
proto_plugin_init()866185db85Sdougm proto_plugin_init()
876185db85Sdougm {
886185db85Sdougm struct sa_proto_plugin *proto;
896185db85Sdougm int num_protos = 0;
906185db85Sdougm struct sa_plugin_ops *plugin_ops;
916185db85Sdougm void *dlhandle;
926185db85Sdougm DIR *dir;
936185db85Sdougm struct dirent *dent;
946185db85Sdougm int ret = SA_OK;
956185db85Sdougm struct stat st;
96549ec3ffSdougm char isa[MAXISALEN];
97549ec3ffSdougm
98549ec3ffSdougm #if defined(_LP64)
99549ec3ffSdougm if (sysinfo(SI_ARCHITECTURE_64, isa, MAXISALEN) == -1)
100549ec3ffSdougm isa[0] = '\0';
101549ec3ffSdougm #else
102549ec3ffSdougm isa[0] = '\0';
103549ec3ffSdougm #endif
104*8d7e4166Sjose borrego
105*8d7e4166Sjose borrego if ((dir = opendir(SA_LIB_DIR)) == NULL)
106*8d7e4166Sjose borrego return (SA_OK);
107*8d7e4166Sjose borrego
108*8d7e4166Sjose borrego while ((dent = readdir(dir)) != NULL) {
109*8d7e4166Sjose borrego char path[MAXPATHLEN];
110*8d7e4166Sjose borrego
111*8d7e4166Sjose borrego if (proto_is_dot_or_dotdot(dent->d_name))
112*8d7e4166Sjose borrego continue;
113*8d7e4166Sjose borrego
1146185db85Sdougm (void) snprintf(path, MAXPATHLEN,
11525a68471Sdougm "%s/%s/%s/libshare_%s.so.1", SA_LIB_DIR,
11625a68471Sdougm dent->d_name, isa, dent->d_name);
117*8d7e4166Sjose borrego
11825a68471Sdougm /*
11925a68471Sdougm * If file doesn't exist, don't try to map it
12025a68471Sdougm */
12125a68471Sdougm if (stat(path, &st) < 0)
1226185db85Sdougm continue;
12325a68471Sdougm
124*8d7e4166Sjose borrego if ((dlhandle = dlopen(path, RTLD_FIRST|RTLD_LAZY)) == NULL) {
125*8d7e4166Sjose borrego (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
126*8d7e4166Sjose borrego "Error in plugin for protocol %s: %s\n"),
127*8d7e4166Sjose borrego dent->d_name, dlerror());
128*8d7e4166Sjose borrego continue;
129*8d7e4166Sjose borrego }
130*8d7e4166Sjose borrego
1316185db85Sdougm plugin_ops = (struct sa_plugin_ops *)
1326185db85Sdougm dlsym(dlhandle, "sa_plugin_ops");
133*8d7e4166Sjose borrego if (plugin_ops == NULL) {
134*8d7e4166Sjose borrego (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
135*8d7e4166Sjose borrego "Error in plugin ops for protocol %s: %s\n"),
136*8d7e4166Sjose borrego dent->d_name, dlerror());
137*8d7e4166Sjose borrego (void) dlclose(dlhandle);
138*8d7e4166Sjose borrego continue;
139*8d7e4166Sjose borrego }
140*8d7e4166Sjose borrego
1416185db85Sdougm proto = (struct sa_proto_plugin *)
1426185db85Sdougm calloc(1, sizeof (struct sa_proto_plugin));
143*8d7e4166Sjose borrego if (proto == NULL) {
144*8d7e4166Sjose borrego (void) dlclose(dlhandle);
145*8d7e4166Sjose borrego ret = SA_NO_MEMORY;
146*8d7e4166Sjose borrego continue;
147*8d7e4166Sjose borrego }
148*8d7e4166Sjose borrego
1496185db85Sdougm proto->plugin_ops = plugin_ops;
1506185db85Sdougm proto->plugin_handle = dlhandle;
1516185db85Sdougm num_protos++;
1526185db85Sdougm proto->plugin_next = sap_proto_list;
1536185db85Sdougm sap_proto_list = proto;
1546185db85Sdougm }
155*8d7e4166Sjose borrego
1566185db85Sdougm (void) closedir(dir);
157*8d7e4166Sjose borrego
158*8d7e4166Sjose borrego if (num_protos != 0) {
1596185db85Sdougm sa_proto_handle.sa_proto =
1606185db85Sdougm (char **)calloc(num_protos, sizeof (char *));
1616185db85Sdougm sa_proto_handle.sa_ops =
1626185db85Sdougm (struct sa_plugin_ops **)calloc(num_protos,
1636185db85Sdougm sizeof (struct sa_plugin_ops *));
1646185db85Sdougm if (sa_proto_handle.sa_proto != NULL &&
1656185db85Sdougm sa_proto_handle.sa_ops != NULL) {
1666185db85Sdougm int i;
1676185db85Sdougm struct sa_proto_plugin *tmp;
16825a68471Sdougm
16925a68471Sdougm for (i = 0, tmp = sap_proto_list;
170917c27c8Sdougm i < num_protos && tmp != NULL;
1716185db85Sdougm tmp = tmp->plugin_next) {
172c5f58477Sdougm int err;
173c5f58477Sdougm err = SA_OK;
1746185db85Sdougm if (tmp->plugin_ops->sa_init != NULL)
1756185db85Sdougm err = tmp->plugin_ops->sa_init();
1766185db85Sdougm if (err == SA_OK) {
17725a68471Sdougm /*
17825a68471Sdougm * Only include if the init
17925a68471Sdougm * succeeded or was NULL
18025a68471Sdougm */
1816185db85Sdougm sa_proto_handle.sa_num_proto++;
18225a68471Sdougm sa_proto_handle.sa_ops[i] =
18325a68471Sdougm tmp->plugin_ops;
1846185db85Sdougm sa_proto_handle.sa_proto[i] =
1856185db85Sdougm tmp->plugin_ops->sa_protocol;
1866185db85Sdougm i++;
1876185db85Sdougm }
1886185db85Sdougm }
1896185db85Sdougm } else {
190c5f58477Sdougm ret = SA_NO_MEMORY;
191c5f58477Sdougm }
192c5f58477Sdougm }
193c5f58477Sdougm
19425a68471Sdougm /*
19525a68471Sdougm * There was an error, so cleanup prior to return of failure.
19625a68471Sdougm */
197c5f58477Sdougm if (ret != SA_OK)
1986185db85Sdougm proto_plugin_fini();
199c5f58477Sdougm
2006185db85Sdougm return (ret);
2016185db85Sdougm }
2026185db85Sdougm
2036185db85Sdougm /*
2046185db85Sdougm * proto_plugin_fini()
2056185db85Sdougm *
20625a68471Sdougm * Uninitialize all the plugin modules.
2076185db85Sdougm */
2086185db85Sdougm
2096185db85Sdougm void
proto_plugin_fini()2106185db85Sdougm proto_plugin_fini()
2116185db85Sdougm {
2120fd77660Sgwr struct sa_proto_plugin *p;
21325a68471Sdougm
2140fd77660Sgwr /*
2150fd77660Sgwr * Protocols may call this framework during _fini
2160fd77660Sgwr * (the smbfs plugin is known to do this) so do
2170fd77660Sgwr * two passes: 1st call _fini; 2nd free, dlclose.
2180fd77660Sgwr */
2190fd77660Sgwr for (p = sap_proto_list; p != NULL; p = p->plugin_next)
2200fd77660Sgwr p->plugin_ops->sa_fini();
2210fd77660Sgwr
2220fd77660Sgwr while ((p = sap_proto_list) != NULL) {
2230fd77660Sgwr sap_proto_list = p->plugin_next;
2240fd77660Sgwr
2250fd77660Sgwr if (p->plugin_handle != NULL)
2260fd77660Sgwr (void) dlclose(p->plugin_handle);
2270fd77660Sgwr free(p);
2286185db85Sdougm }
2296185db85Sdougm if (sa_proto_handle.sa_ops != NULL) {
2306185db85Sdougm free(sa_proto_handle.sa_ops);
2316185db85Sdougm sa_proto_handle.sa_ops = NULL;
2326185db85Sdougm }
2336185db85Sdougm if (sa_proto_handle.sa_proto != NULL) {
2346185db85Sdougm free(sa_proto_handle.sa_proto);
2356185db85Sdougm sa_proto_handle.sa_proto = NULL;
2366185db85Sdougm }
2376185db85Sdougm sa_proto_handle.sa_num_proto = 0;
2386185db85Sdougm }
2396185db85Sdougm
2406185db85Sdougm /*
2416185db85Sdougm * find_protocol(proto)
2426185db85Sdougm *
2436185db85Sdougm * Search the plugin list for the specified protocol and return the
2446185db85Sdougm * ops vector. NULL if protocol is not defined.
2456185db85Sdougm */
2466185db85Sdougm
2476185db85Sdougm static struct sa_plugin_ops *
find_protocol(char * proto)2486185db85Sdougm find_protocol(char *proto)
2496185db85Sdougm {
2506185db85Sdougm int i;
251c5f58477Sdougm struct sa_plugin_ops *ops = NULL;
252c5f58477Sdougm extern mutex_t sa_global_lock;
2536185db85Sdougm
254c5f58477Sdougm (void) mutex_lock(&sa_global_lock);
2556185db85Sdougm if (proto != NULL) {
2566185db85Sdougm for (i = 0; i < sa_proto_handle.sa_num_proto; i++) {
257c5f58477Sdougm if (strcmp(proto, sa_proto_handle.sa_proto[i]) == 0) {
258c5f58477Sdougm ops = sa_proto_handle.sa_ops[i];
259c5f58477Sdougm break;
2606185db85Sdougm }
2616185db85Sdougm }
262c5f58477Sdougm }
263c5f58477Sdougm (void) mutex_unlock(&sa_global_lock);
264c5f58477Sdougm return (ops);
2656185db85Sdougm }
2666185db85Sdougm
2676185db85Sdougm /*
2686185db85Sdougm * sa_proto_share(proto, share)
2696185db85Sdougm *
2706185db85Sdougm * Activate a share for the specified protocol.
2716185db85Sdougm */
2726185db85Sdougm
2736185db85Sdougm int
sa_proto_share(char * proto,sa_share_t share)2746185db85Sdougm sa_proto_share(char *proto, sa_share_t share)
2756185db85Sdougm {
2766185db85Sdougm struct sa_plugin_ops *ops = find_protocol(proto);
2776185db85Sdougm int ret = SA_INVALID_PROTOCOL;
2786185db85Sdougm
2796185db85Sdougm if (ops != NULL && ops->sa_share != NULL)
2806185db85Sdougm ret = ops->sa_share(share);
2816185db85Sdougm return (ret);
2826185db85Sdougm }
2836185db85Sdougm
2846185db85Sdougm /*
285da6c28aaSamw * sa_proto_unshare(proto, share)
2866185db85Sdougm *
287da6c28aaSamw * Deactivate (unshare) the share for this protocol.
2886185db85Sdougm */
2896185db85Sdougm
2906185db85Sdougm int
sa_proto_unshare(sa_share_t share,char * proto,char * path)291ecd6cf80Smarks sa_proto_unshare(sa_share_t share, char *proto, char *path)
2926185db85Sdougm {
2936185db85Sdougm struct sa_plugin_ops *ops = find_protocol(proto);
2946185db85Sdougm int ret = SA_INVALID_PROTOCOL;
2956185db85Sdougm
2966185db85Sdougm if (ops != NULL && ops->sa_unshare != NULL)
297ecd6cf80Smarks ret = ops->sa_unshare(share, path);
2986185db85Sdougm return (ret);
2996185db85Sdougm }
3006185db85Sdougm
3016185db85Sdougm /*
302da6c28aaSamw * sa_proto_share_resource(char *proto, sa_resource_t resource)
303da6c28aaSamw *
304da6c28aaSamw * For protocols that actually enable at the resource level, do the
305da6c28aaSamw * protocol specific resource enable. If it doesn't, return an error.
306da6c28aaSamw * Note that the resource functions are optional so can return
307da6c28aaSamw * SA_NOT_SUPPORTED.
308da6c28aaSamw */
309da6c28aaSamw
310da6c28aaSamw int
sa_proto_share_resource(char * proto,sa_resource_t resource)311da6c28aaSamw sa_proto_share_resource(char *proto, sa_resource_t resource)
312da6c28aaSamw {
313da6c28aaSamw struct sa_plugin_ops *ops = find_protocol(proto);
314da6c28aaSamw int ret = SA_INVALID_PROTOCOL;
315da6c28aaSamw
316da6c28aaSamw if (ops != NULL) {
317da6c28aaSamw if (ops->sa_enable_resource != NULL)
318da6c28aaSamw ret = ops->sa_enable_resource(resource);
319da6c28aaSamw else
320da6c28aaSamw ret = SA_NOT_SUPPORTED;
321da6c28aaSamw }
322da6c28aaSamw return (ret);
323da6c28aaSamw }
324da6c28aaSamw
325da6c28aaSamw /*
326da6c28aaSamw * sa_proto_unshare_resource(char *proto, sa_resource_t resource)
327da6c28aaSamw *
328da6c28aaSamw * For protocols that actually disable at the resource level, do the
329da6c28aaSamw * protocol specific resource disable. If it doesn't, return an error.
330da6c28aaSamw */
331da6c28aaSamw
332da6c28aaSamw int
sa_proto_unshare_resource(char * proto,sa_resource_t resource)333da6c28aaSamw sa_proto_unshare_resource(char *proto, sa_resource_t resource)
334da6c28aaSamw {
335da6c28aaSamw struct sa_plugin_ops *ops = find_protocol(proto);
336da6c28aaSamw int ret = SA_INVALID_PROTOCOL;
337da6c28aaSamw
338da6c28aaSamw if (ops != NULL) {
339da6c28aaSamw if (ops->sa_disable_resource != NULL)
340da6c28aaSamw ret = ops->sa_disable_resource(resource);
341da6c28aaSamw else
342da6c28aaSamw ret = SA_NOT_SUPPORTED;
343da6c28aaSamw }
344da6c28aaSamw return (ret);
345da6c28aaSamw }
346da6c28aaSamw
347da6c28aaSamw /*
348687915e9Sdougm * sa_proto_valid_prop(handle, proto, prop, opt)
3496185db85Sdougm *
35025a68471Sdougm * Check to see if the specified prop is valid for this protocol.
3516185db85Sdougm */
3526185db85Sdougm
3536185db85Sdougm int
sa_proto_valid_prop(sa_handle_t handle,char * proto,sa_property_t prop,sa_optionset_t opt)354687915e9Sdougm sa_proto_valid_prop(sa_handle_t handle, char *proto, sa_property_t prop,
355687915e9Sdougm sa_optionset_t opt)
3566185db85Sdougm {
3576185db85Sdougm struct sa_plugin_ops *ops = find_protocol(proto);
3586185db85Sdougm int ret = 0;
3596185db85Sdougm
3606185db85Sdougm if (ops != NULL && ops->sa_valid_prop != NULL)
361687915e9Sdougm ret = ops->sa_valid_prop(handle, prop, opt);
3626185db85Sdougm return (ret);
3636185db85Sdougm }
3646185db85Sdougm
3656185db85Sdougm /*
3666185db85Sdougm * sa_proto_valid_space(proto, space)
3676185db85Sdougm *
36825a68471Sdougm * Check if space is valid optionspace for proto.
3696185db85Sdougm * Protocols that don't implement this don't support spaces.
3706185db85Sdougm */
3716185db85Sdougm int
sa_proto_valid_space(char * proto,char * token)3726185db85Sdougm sa_proto_valid_space(char *proto, char *token)
3736185db85Sdougm {
3746185db85Sdougm struct sa_plugin_ops *ops = find_protocol(proto);
3756185db85Sdougm int ret = 0;
3766185db85Sdougm
3776185db85Sdougm if (ops != NULL && ops->sa_valid_space != NULL)
3786185db85Sdougm ret = ops->sa_valid_space(token);
3796185db85Sdougm return (ret);
3806185db85Sdougm }
3816185db85Sdougm
3826185db85Sdougm /*
3836185db85Sdougm * sa_proto_space_alias(proto, space)
3846185db85Sdougm *
38525a68471Sdougm * If the name for space is an alias, return its proper name. This is
3866185db85Sdougm * used to translate "default" values into proper form.
3876185db85Sdougm */
3886185db85Sdougm char *
sa_proto_space_alias(char * proto,char * space)3896185db85Sdougm sa_proto_space_alias(char *proto, char *space)
3906185db85Sdougm {
3916185db85Sdougm struct sa_plugin_ops *ops = find_protocol(proto);
3926185db85Sdougm char *ret = space;
3936185db85Sdougm
3946185db85Sdougm if (ops != NULL && ops->sa_space_alias != NULL)
3956185db85Sdougm ret = ops->sa_space_alias(space);
3966185db85Sdougm return (ret);
3976185db85Sdougm }
3986185db85Sdougm
3996185db85Sdougm /*
4006185db85Sdougm * sa_proto_security_prop(proto, token)
4016185db85Sdougm *
4026185db85Sdougm * Check to see if the property name in token is a valid named
4036185db85Sdougm * optionset property.
4046185db85Sdougm */
4056185db85Sdougm
4066185db85Sdougm int
sa_proto_security_prop(char * proto,char * token)4076185db85Sdougm sa_proto_security_prop(char *proto, char *token)
4086185db85Sdougm {
4096185db85Sdougm struct sa_plugin_ops *ops = find_protocol(proto);
4106185db85Sdougm int ret = 0;
4116185db85Sdougm
4126185db85Sdougm if (ops != NULL && ops->sa_security_prop != NULL)
4136185db85Sdougm ret = ops->sa_security_prop(token);
4146185db85Sdougm return (ret);
4156185db85Sdougm }
4166185db85Sdougm
4176185db85Sdougm /*
4186185db85Sdougm * sa_proto_legacy_opts(proto, grouup, options)
4196185db85Sdougm *
4206185db85Sdougm * Have the protocol specific parser parse the options string and add
4216185db85Sdougm * an appropriate optionset to group.
4226185db85Sdougm */
4236185db85Sdougm
4246185db85Sdougm int
sa_proto_legacy_opts(char * proto,sa_group_t group,char * options)4256185db85Sdougm sa_proto_legacy_opts(char *proto, sa_group_t group, char *options)
4266185db85Sdougm {
4276185db85Sdougm struct sa_plugin_ops *ops = find_protocol(proto);
4286185db85Sdougm int ret = SA_INVALID_PROTOCOL;
4296185db85Sdougm
4306185db85Sdougm if (ops != NULL && ops->sa_legacy_opts != NULL)
4316185db85Sdougm ret = ops->sa_legacy_opts(group, options);
4326185db85Sdougm return (ret);
4336185db85Sdougm }
4346185db85Sdougm
4356185db85Sdougm /*
4366185db85Sdougm * sa_proto_legacy_format(proto, group, hier)
4376185db85Sdougm *
4386185db85Sdougm * Return a legacy format string representing either the group's
4396185db85Sdougm * properties or the groups hierarchical properties.
4406185db85Sdougm */
4416185db85Sdougm
4426185db85Sdougm char *
sa_proto_legacy_format(char * proto,sa_group_t group,int hier)4436185db85Sdougm sa_proto_legacy_format(char *proto, sa_group_t group, int hier)
4446185db85Sdougm {
4456185db85Sdougm struct sa_plugin_ops *ops = find_protocol(proto);
4466185db85Sdougm char *ret = NULL;
4476185db85Sdougm
4486185db85Sdougm if (ops != NULL && ops->sa_legacy_format != NULL)
4496185db85Sdougm ret = ops->sa_legacy_format(group, hier);
4506185db85Sdougm return (ret);
4516185db85Sdougm }
4526185db85Sdougm
4536185db85Sdougm void
sa_format_free(char * str)4546185db85Sdougm sa_format_free(char *str)
4556185db85Sdougm {
4566185db85Sdougm free(str);
4576185db85Sdougm }
4586185db85Sdougm
4596185db85Sdougm /*
4606185db85Sdougm * sharectl related API functions
4616185db85Sdougm */
4626185db85Sdougm
4636185db85Sdougm /*
4646185db85Sdougm * sa_proto_get_properties(proto)
4656185db85Sdougm *
4666185db85Sdougm * Return the set of properties that are specific to the
4676185db85Sdougm * protocol. These are usually in /etc/dfs/<proto> and related files,
4686185db85Sdougm * but only the protocol module knows which ones for sure.
4696185db85Sdougm */
4706185db85Sdougm
4716185db85Sdougm sa_protocol_properties_t
sa_proto_get_properties(char * proto)4726185db85Sdougm sa_proto_get_properties(char *proto)
4736185db85Sdougm {
4746185db85Sdougm struct sa_plugin_ops *ops = find_protocol(proto);
4756185db85Sdougm sa_protocol_properties_t props = NULL;
4766185db85Sdougm
4776185db85Sdougm if (ops != NULL && ops->sa_get_proto_set != NULL)
4786185db85Sdougm props = ops->sa_get_proto_set();
4796185db85Sdougm return (props);
4806185db85Sdougm }
4816185db85Sdougm
4826185db85Sdougm /*
4836185db85Sdougm * sa_proto_set_property(proto, prop)
4846185db85Sdougm *
485da6c28aaSamw * Update the protocol specific property.
4866185db85Sdougm */
4876185db85Sdougm
4886185db85Sdougm int
sa_proto_set_property(char * proto,sa_property_t prop)4896185db85Sdougm sa_proto_set_property(char *proto, sa_property_t prop)
4906185db85Sdougm {
4916185db85Sdougm struct sa_plugin_ops *ops = find_protocol(proto);
4926185db85Sdougm int ret = SA_OK;
49325a68471Sdougm
4946185db85Sdougm if (ops != NULL && ops->sa_set_proto_prop != NULL)
4956185db85Sdougm ret = ops->sa_set_proto_prop(prop);
4966185db85Sdougm return (ret);
4976185db85Sdougm }
4986185db85Sdougm
4996185db85Sdougm /*
5006185db85Sdougm * sa_valid_protocol(proto)
5016185db85Sdougm *
50225a68471Sdougm * Check to see if the protocol specified is defined by a
5036185db85Sdougm * plugin. Returns true (1) or false (0)
5046185db85Sdougm */
5056185db85Sdougm
5066185db85Sdougm int
sa_valid_protocol(char * proto)5076185db85Sdougm sa_valid_protocol(char *proto)
5086185db85Sdougm {
5096185db85Sdougm struct sa_plugin_ops *ops = find_protocol(proto);
5106185db85Sdougm return (ops != NULL);
5116185db85Sdougm }
5126185db85Sdougm
5136185db85Sdougm /*
5146185db85Sdougm * Return the current operational status of the protocol
5156185db85Sdougm */
5166185db85Sdougm
5176185db85Sdougm char *
sa_get_protocol_status(char * proto)5186185db85Sdougm sa_get_protocol_status(char *proto)
5196185db85Sdougm {
5206185db85Sdougm struct sa_plugin_ops *ops = find_protocol(proto);
5216185db85Sdougm char *ret = NULL;
5226185db85Sdougm if (ops != NULL && ops->sa_get_proto_status != NULL)
5236185db85Sdougm ret = ops->sa_get_proto_status(proto);
5246185db85Sdougm return (ret);
5256185db85Sdougm }
5266185db85Sdougm
5276185db85Sdougm /*
5286185db85Sdougm * sa_proto_update_legacy(proto, share)
5296185db85Sdougm *
5306185db85Sdougm * Update the protocol specific legacy files if necessary for the
5316185db85Sdougm * specified share.
5326185db85Sdougm */
5336185db85Sdougm
5346185db85Sdougm int
sa_proto_update_legacy(char * proto,sa_share_t share)5356185db85Sdougm sa_proto_update_legacy(char *proto, sa_share_t share)
5366185db85Sdougm {
5376185db85Sdougm struct sa_plugin_ops *ops = find_protocol(proto);
5386185db85Sdougm int ret = SA_NOT_IMPLEMENTED;
5396185db85Sdougm
5406185db85Sdougm if (ops != NULL) {
5416185db85Sdougm if (ops->sa_update_legacy != NULL)
5426185db85Sdougm ret = ops->sa_update_legacy(share);
5436185db85Sdougm }
5446185db85Sdougm return (ret);
5456185db85Sdougm }
5466185db85Sdougm
5476185db85Sdougm /*
5486185db85Sdougm * sa_delete_legacy(proto, share)
5496185db85Sdougm *
55025a68471Sdougm * Remove the specified share from the protocol specific legacy files.
5516185db85Sdougm */
5526185db85Sdougm
5536185db85Sdougm int
sa_proto_delete_legacy(char * proto,sa_share_t share)5546185db85Sdougm sa_proto_delete_legacy(char *proto, sa_share_t share)
5556185db85Sdougm {
5566185db85Sdougm struct sa_plugin_ops *ops = find_protocol(proto);
557da6c28aaSamw int ret = SA_NOT_IMPLEMENTED;
5586185db85Sdougm
5596185db85Sdougm if (ops != NULL) {
5606185db85Sdougm if (ops->sa_delete_legacy != NULL)
5616185db85Sdougm ret = ops->sa_delete_legacy(share);
5624bff34e3Sthurlow } else {
5634bff34e3Sthurlow if (proto != NULL)
5644bff34e3Sthurlow ret = SA_NOT_IMPLEMENTED;
5654bff34e3Sthurlow else
5664bff34e3Sthurlow ret = SA_INVALID_PROTOCOL;
5674bff34e3Sthurlow }
5684bff34e3Sthurlow return (ret);
5694bff34e3Sthurlow }
5704bff34e3Sthurlow
5714bff34e3Sthurlow /*
5724bff34e3Sthurlow * sa_proto_delete_section(proto, section)
5734bff34e3Sthurlow *
5744bff34e3Sthurlow * Remove the specified section from the protocol specific legacy files,
5754bff34e3Sthurlow * if supported.
5764bff34e3Sthurlow */
5774bff34e3Sthurlow
5784bff34e3Sthurlow int
sa_proto_delete_section(char * proto,char * section)5794bff34e3Sthurlow sa_proto_delete_section(char *proto, char *section)
5804bff34e3Sthurlow {
5814bff34e3Sthurlow struct sa_plugin_ops *ops = find_protocol(proto);
5824bff34e3Sthurlow int ret = SA_OK;
5834bff34e3Sthurlow
5844bff34e3Sthurlow if (ops != NULL) {
5854bff34e3Sthurlow if (ops->sa_delete_proto_section != NULL)
5864bff34e3Sthurlow ret = ops->sa_delete_proto_section(section);
5874bff34e3Sthurlow } else {
5884bff34e3Sthurlow if (proto != NULL)
5894bff34e3Sthurlow ret = SA_NOT_IMPLEMENTED;
5904bff34e3Sthurlow else
5916185db85Sdougm ret = SA_INVALID_PROTOCOL;
5926185db85Sdougm }
5936185db85Sdougm return (ret);
5946185db85Sdougm }
595da6c28aaSamw
596da6c28aaSamw /*
597da6c28aaSamw * sa_proto_change_notify(share, char *protocol)
598da6c28aaSamw *
599da6c28aaSamw * Notify the protocol that a change has been made to the share
600da6c28aaSamw */
601da6c28aaSamw
602da6c28aaSamw int
sa_proto_change_notify(sa_share_t share,char * proto)603da6c28aaSamw sa_proto_change_notify(sa_share_t share, char *proto)
604da6c28aaSamw {
605da6c28aaSamw struct sa_plugin_ops *ops = find_protocol(proto);
606da6c28aaSamw int ret = SA_NOT_IMPLEMENTED;
607da6c28aaSamw
608da6c28aaSamw if (ops != NULL) {
609da6c28aaSamw if (ops->sa_change_notify != NULL)
610da6c28aaSamw ret = ops->sa_change_notify(share);
611da6c28aaSamw } else if (proto == NULL) {
6124bff34e3Sthurlow
613da6c28aaSamw ret = SA_INVALID_PROTOCOL;
614da6c28aaSamw }
615da6c28aaSamw return (ret);
616da6c28aaSamw }
617da6c28aaSamw
618da6c28aaSamw /*
619da6c28aaSamw * sa_proto_notify_resource(resource, char *protocol)
620da6c28aaSamw *
621da6c28aaSamw * Notify the protocol that a change has been made to the share
622da6c28aaSamw */
623da6c28aaSamw
624da6c28aaSamw int
sa_proto_notify_resource(sa_resource_t resource,char * proto)625da6c28aaSamw sa_proto_notify_resource(sa_resource_t resource, char *proto)
626da6c28aaSamw {
627da6c28aaSamw struct sa_plugin_ops *ops = find_protocol(proto);
628da6c28aaSamw int ret = SA_NOT_IMPLEMENTED;
629da6c28aaSamw
630da6c28aaSamw if (ops != NULL) {
631da6c28aaSamw if (ops->sa_notify_resource != NULL)
632da6c28aaSamw ret = ops->sa_notify_resource(resource);
633da6c28aaSamw } else if (proto == NULL) {
634da6c28aaSamw ret = SA_INVALID_PROTOCOL;
635da6c28aaSamw }
636da6c28aaSamw return (ret);
637da6c28aaSamw }
638da6c28aaSamw
639da6c28aaSamw /*
640da6c28aaSamw * sa_proto_get_featureset(protocol)
641da6c28aaSamw *
642da6c28aaSamw * Get bitmask of defined features of the protocol. These are
643da6c28aaSamw * primarily things like SA_FEATURE_RESOURCE (shares are by resource
644da6c28aaSamw * name rather than path) and other operational features that affect
645da6c28aaSamw * behavior.
646da6c28aaSamw */
647da6c28aaSamw
648da6c28aaSamw uint64_t
sa_proto_get_featureset(char * proto)649da6c28aaSamw sa_proto_get_featureset(char *proto)
650da6c28aaSamw {
651da6c28aaSamw struct sa_plugin_ops *ops = find_protocol(proto);
652da6c28aaSamw uint64_t ret = 0;
653da6c28aaSamw
654da6c28aaSamw if (ops != NULL) {
655da6c28aaSamw if (ops->sa_features != NULL)
656da6c28aaSamw ret = ops->sa_features();
657da6c28aaSamw }
658da6c28aaSamw /* if not implemented, zero is valid */
659da6c28aaSamw return (ret);
660da6c28aaSamw }
661da6c28aaSamw
662da6c28aaSamw /*
663da6c28aaSamw * sa_proto_get_transients(sa_handle_t)
664da6c28aaSamw *
665da6c28aaSamw * Called to get any protocol specific transient shares. NFS doesn't
666da6c28aaSamw * use this since the info is in sharetab which is processed as a
667da6c28aaSamw * common transient store.
668da6c28aaSamw *
669da6c28aaSamw * The protocol plugin should verify that the share isn't in the
670da6c28aaSamw * repository and then add it as a transient.
671da6c28aaSamw *
672da6c28aaSamw * Not having an entry is not a problem. It returns 0 in that case.
673da6c28aaSamw */
674da6c28aaSamw
675da6c28aaSamw int
sa_proto_get_transients(sa_handle_t handle,char * proto)676da6c28aaSamw sa_proto_get_transients(sa_handle_t handle, char *proto)
677da6c28aaSamw {
678da6c28aaSamw struct sa_plugin_ops *ops = find_protocol(proto);
679da6c28aaSamw int ret = 0;
680da6c28aaSamw
681da6c28aaSamw if (ops != NULL) {
682da6c28aaSamw if (ops->sa_get_transient_shares != NULL)
683da6c28aaSamw ret = ops->sa_get_transient_shares(handle);
684da6c28aaSamw }
685da6c28aaSamw return (ret);
686da6c28aaSamw }
687da6c28aaSamw
688da6c28aaSamw /*
689da6c28aaSamw * sa_proto_rename_resource(sa_handle_t, proto, sa_resource_t, newname)
690da6c28aaSamw *
691da6c28aaSamw * Protocols may need to know when a resource has changed names in
692da6c28aaSamw * order to notify clients. This must be done "before" the name in the
693da6c28aaSamw * resource has been changed. Not being implemented is not a problem.
694da6c28aaSamw */
695da6c28aaSamw
696da6c28aaSamw int
sa_proto_rename_resource(sa_handle_t handle,char * proto,sa_resource_t resource,char * newname)697da6c28aaSamw sa_proto_rename_resource(sa_handle_t handle, char *proto,
698da6c28aaSamw sa_resource_t resource, char *newname)
699da6c28aaSamw {
700da6c28aaSamw struct sa_plugin_ops *ops = find_protocol(proto);
701da6c28aaSamw int ret = SA_OK;
702da6c28aaSamw
703da6c28aaSamw if (ops != NULL) {
704da6c28aaSamw if (ops->sa_rename_resource != NULL)
705da6c28aaSamw ret = ops->sa_rename_resource(handle, resource,
706da6c28aaSamw newname);
707da6c28aaSamw }
708da6c28aaSamw return (ret);
709da6c28aaSamw }
710