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 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 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 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 * 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 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 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 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 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 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 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 * 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 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 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 * 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 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 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 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 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 * 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 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 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 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 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 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 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 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 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