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 #pragma ident "%Z%%M% %I% %E% SMI" 283034Sdougm 293034Sdougm #include <stdio.h> 303034Sdougm #include <stdlib.h> 313034Sdougm #include <string.h> 323034Sdougm #include <libshare.h> 333034Sdougm #include "libshare_impl.h" 343034Sdougm #include <dlfcn.h> 353034Sdougm #include <link.h> 363034Sdougm #include <sys/types.h> 373034Sdougm #include <sys/param.h> 383034Sdougm #include <sys/stat.h> 393034Sdougm #include <dirent.h> 403034Sdougm #include <libintl.h> 413910Sdougm #include <sys/systeminfo.h> 426304Sdougm #include <thread.h> 436304Sdougm #include <synch.h> 443910Sdougm 453910Sdougm #define MAXISALEN 257 /* based on sysinfo(2) man page */ 463034Sdougm 473034Sdougm /* 483034Sdougm * protocol plugin interface 493034Sdougm * 503034Sdougm * finds plugins and makes them accessible. This is only "used" by 513034Sdougm * libshare.so. 523034Sdougm */ 533034Sdougm 543034Sdougm struct sa_proto_plugin *sap_proto_list; 553034Sdougm 563034Sdougm static struct sa_proto_handle sa_proto_handle; 573034Sdougm 583034Sdougm void proto_plugin_fini(); 593034Sdougm 603034Sdougm /* 613034Sdougm * proto_plugin_init() 623034Sdougm * 633034Sdougm * Initialize the protocol specific plugin modules. 643034Sdougm * 653034Sdougm * Walk /usr/lib/fs/\* for libshare_*.so modules. That is, 663034Sdougm * /usr/lib/fs/nfs/libshare_nfs.so. The protocol specific directory 673034Sdougm * would have a modules with name libshare_<proto>.so. If one is 683034Sdougm * found, initialize it and add to the internal list of 695331Samw * protocols. These are used for protocol specific operations. 703034Sdougm */ 713034Sdougm 723034Sdougm int 733034Sdougm proto_plugin_init() 743034Sdougm { 753034Sdougm struct sa_proto_plugin *proto; 763034Sdougm int num_protos = 0; 773034Sdougm struct sa_plugin_ops *plugin_ops; 783034Sdougm void *dlhandle; 793034Sdougm DIR *dir; 803034Sdougm struct dirent *dent; 813034Sdougm int ret = SA_OK; 823034Sdougm struct stat st; 833034Sdougm 843034Sdougm /* 854653Sdougm * Should walk "/usr/lib/fs/" for files of the form: 863034Sdougm * libshare_*.so 873034Sdougm */ 883034Sdougm dir = opendir(SA_LIB_DIR); 893034Sdougm if (dir != NULL) { 904653Sdougm while (ret == SA_OK && (dent = readdir(dir)) != NULL) { 914653Sdougm char path[MAXPATHLEN]; 924653Sdougm char isa[MAXISALEN]; 933910Sdougm 943910Sdougm #if defined(_LP64) 954653Sdougm if (sysinfo(SI_ARCHITECTURE_64, isa, MAXISALEN) == -1) 964653Sdougm isa[0] = '\0'; 973910Sdougm #else 984653Sdougm isa[0] = '\0'; 993910Sdougm #endif 1004653Sdougm (void) snprintf(path, MAXPATHLEN, 1014653Sdougm "%s/%s/%s/libshare_%s.so.1", SA_LIB_DIR, 1024653Sdougm dent->d_name, isa, dent->d_name); 1034653Sdougm /* 1044653Sdougm * If file doesn't exist, don't try to map it 1054653Sdougm */ 1064653Sdougm if (stat(path, &st) < 0) 1074653Sdougm continue; 1084653Sdougm 1094653Sdougm dlhandle = dlopen(path, RTLD_FIRST|RTLD_LAZY); 1104653Sdougm if (dlhandle != NULL) { 1114653Sdougm plugin_ops = (struct sa_plugin_ops *) 1124653Sdougm dlsym(dlhandle, "sa_plugin_ops"); 1134653Sdougm proto = (struct sa_proto_plugin *) 1144653Sdougm calloc(1, sizeof (struct sa_proto_plugin)); 1154653Sdougm if (proto != NULL) { 1164653Sdougm proto->plugin_ops = plugin_ops; 1174653Sdougm proto->plugin_handle = dlhandle; 1184653Sdougm num_protos++; 1194653Sdougm proto->plugin_next = sap_proto_list; 1204653Sdougm sap_proto_list = proto; 1214653Sdougm } else { 1224653Sdougm ret = SA_NO_MEMORY; 1236304Sdougm /* Don't leak a dlhandle */ 1246304Sdougm (void) dlclose(dlhandle); 1256304Sdougm break; 1264653Sdougm } 1274653Sdougm } else { 1284653Sdougm (void) fprintf(stderr, 1294653Sdougm dgettext(TEXT_DOMAIN, 1304653Sdougm "Error in plugin for protocol %s: %s\n"), 1314653Sdougm dent->d_name, dlerror()); 1324653Sdougm } 1333034Sdougm } 1344653Sdougm (void) closedir(dir); 1353034Sdougm } 1363034Sdougm if (ret == SA_OK) { 1374653Sdougm sa_proto_handle.sa_proto = 1384653Sdougm (char **)calloc(num_protos, sizeof (char *)); 1394653Sdougm sa_proto_handle.sa_ops = 1404653Sdougm (struct sa_plugin_ops **)calloc(num_protos, 1414653Sdougm sizeof (struct sa_plugin_ops *)); 1424653Sdougm if (sa_proto_handle.sa_proto != NULL && 1434653Sdougm sa_proto_handle.sa_ops != NULL) { 1444653Sdougm int i; 1454653Sdougm struct sa_proto_plugin *tmp; 1464653Sdougm 1474653Sdougm for (i = 0, tmp = sap_proto_list; 1486162Sdougm i < num_protos && tmp != NULL; 1494653Sdougm tmp = tmp->plugin_next) { 1506304Sdougm int err; 1516304Sdougm err = SA_OK; 1524653Sdougm if (tmp->plugin_ops->sa_init != NULL) 1534653Sdougm err = tmp->plugin_ops->sa_init(); 1544653Sdougm if (err == SA_OK) { 1554653Sdougm /* 1564653Sdougm * Only include if the init 1574653Sdougm * succeeded or was NULL 1584653Sdougm */ 1594653Sdougm sa_proto_handle.sa_num_proto++; 1604653Sdougm sa_proto_handle.sa_ops[i] = 1614653Sdougm tmp->plugin_ops; 1624653Sdougm sa_proto_handle.sa_proto[i] = 1634653Sdougm tmp->plugin_ops->sa_protocol; 1644653Sdougm i++; 1654653Sdougm } 1664653Sdougm } 1676304Sdougm } else { 1686304Sdougm ret = SA_NO_MEMORY; 1693034Sdougm } 1706304Sdougm } 1716304Sdougm 1726304Sdougm /* 1736304Sdougm * There was an error, so cleanup prior to return of failure. 1746304Sdougm */ 1756304Sdougm if (ret != SA_OK) 1764653Sdougm proto_plugin_fini(); 1776304Sdougm 1783034Sdougm return (ret); 1793034Sdougm } 1803034Sdougm 1813034Sdougm /* 1823034Sdougm * proto_plugin_fini() 1833034Sdougm * 1844653Sdougm * Uninitialize all the plugin modules. 1853034Sdougm */ 1863034Sdougm 1873034Sdougm void 1883034Sdougm proto_plugin_fini() 1893034Sdougm { 190*7010Sgwr struct sa_proto_plugin *p; 1914653Sdougm 192*7010Sgwr /* 193*7010Sgwr * Protocols may call this framework during _fini 194*7010Sgwr * (the smbfs plugin is known to do this) so do 195*7010Sgwr * two passes: 1st call _fini; 2nd free, dlclose. 196*7010Sgwr */ 197*7010Sgwr for (p = sap_proto_list; p != NULL; p = p->plugin_next) 198*7010Sgwr p->plugin_ops->sa_fini(); 199*7010Sgwr 200*7010Sgwr while ((p = sap_proto_list) != NULL) { 201*7010Sgwr sap_proto_list = p->plugin_next; 202*7010Sgwr 203*7010Sgwr if (p->plugin_handle != NULL) 204*7010Sgwr (void) dlclose(p->plugin_handle); 205*7010Sgwr free(p); 2063034Sdougm } 2073034Sdougm if (sa_proto_handle.sa_ops != NULL) { 2084653Sdougm free(sa_proto_handle.sa_ops); 2094653Sdougm sa_proto_handle.sa_ops = NULL; 2103034Sdougm } 2113034Sdougm if (sa_proto_handle.sa_proto != NULL) { 2124653Sdougm free(sa_proto_handle.sa_proto); 2134653Sdougm sa_proto_handle.sa_proto = NULL; 2143034Sdougm } 2153034Sdougm sa_proto_handle.sa_num_proto = 0; 2163034Sdougm } 2173034Sdougm 2183034Sdougm /* 2193034Sdougm * find_protocol(proto) 2203034Sdougm * 2213034Sdougm * Search the plugin list for the specified protocol and return the 2223034Sdougm * ops vector. NULL if protocol is not defined. 2233034Sdougm */ 2243034Sdougm 2253034Sdougm static struct sa_plugin_ops * 2263034Sdougm find_protocol(char *proto) 2273034Sdougm { 2283034Sdougm int i; 2296304Sdougm struct sa_plugin_ops *ops = NULL; 2306304Sdougm extern mutex_t sa_global_lock; 2313034Sdougm 2326304Sdougm (void) mutex_lock(&sa_global_lock); 2333034Sdougm if (proto != NULL) { 2344653Sdougm for (i = 0; i < sa_proto_handle.sa_num_proto; i++) { 2356304Sdougm if (strcmp(proto, sa_proto_handle.sa_proto[i]) == 0) { 2366304Sdougm ops = sa_proto_handle.sa_ops[i]; 2376304Sdougm break; 2386304Sdougm } 2394653Sdougm } 2403034Sdougm } 2416304Sdougm (void) mutex_unlock(&sa_global_lock); 2426304Sdougm return (ops); 2433034Sdougm } 2443034Sdougm 2453034Sdougm /* 2463034Sdougm * sa_proto_share(proto, share) 2473034Sdougm * 2483034Sdougm * Activate a share for the specified protocol. 2493034Sdougm */ 2503034Sdougm 2513034Sdougm int 2523034Sdougm sa_proto_share(char *proto, sa_share_t share) 2533034Sdougm { 2543034Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 2553034Sdougm int ret = SA_INVALID_PROTOCOL; 2563034Sdougm 2573034Sdougm if (ops != NULL && ops->sa_share != NULL) 2584653Sdougm ret = ops->sa_share(share); 2593034Sdougm return (ret); 2603034Sdougm } 2613034Sdougm 2623034Sdougm /* 2635331Samw * sa_proto_unshare(proto, share) 2643034Sdougm * 2655331Samw * Deactivate (unshare) the share for this protocol. 2663034Sdougm */ 2673034Sdougm 2683034Sdougm int 2694543Smarks sa_proto_unshare(sa_share_t share, char *proto, char *path) 2703034Sdougm { 2713034Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 2723034Sdougm int ret = SA_INVALID_PROTOCOL; 2733034Sdougm 2743034Sdougm if (ops != NULL && ops->sa_unshare != NULL) 2754653Sdougm ret = ops->sa_unshare(share, path); 2763034Sdougm return (ret); 2773034Sdougm } 2783034Sdougm 2793034Sdougm /* 2805331Samw * sa_proto_share_resource(char *proto, sa_resource_t resource) 2815331Samw * 2825331Samw * For protocols that actually enable at the resource level, do the 2835331Samw * protocol specific resource enable. If it doesn't, return an error. 2845331Samw * Note that the resource functions are optional so can return 2855331Samw * SA_NOT_SUPPORTED. 2865331Samw */ 2875331Samw 2885331Samw int 2895331Samw sa_proto_share_resource(char *proto, sa_resource_t resource) 2905331Samw { 2915331Samw struct sa_plugin_ops *ops = find_protocol(proto); 2925331Samw int ret = SA_INVALID_PROTOCOL; 2935331Samw 2945331Samw if (ops != NULL) { 2955331Samw if (ops->sa_enable_resource != NULL) 2965331Samw ret = ops->sa_enable_resource(resource); 2975331Samw else 2985331Samw ret = SA_NOT_SUPPORTED; 2995331Samw } 3005331Samw return (ret); 3015331Samw } 3025331Samw 3035331Samw /* 3045331Samw * sa_proto_unshare_resource(char *proto, sa_resource_t resource) 3055331Samw * 3065331Samw * For protocols that actually disable at the resource level, do the 3075331Samw * protocol specific resource disable. If it doesn't, return an error. 3085331Samw */ 3095331Samw 3105331Samw int 3115331Samw sa_proto_unshare_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_disable_resource != NULL) 3185331Samw ret = ops->sa_disable_resource(resource); 3195331Samw else 3205331Samw ret = SA_NOT_SUPPORTED; 3215331Samw } 3225331Samw return (ret); 3235331Samw } 3245331Samw 3255331Samw /* 3266214Sdougm * sa_proto_valid_prop(handle, proto, prop, opt) 3273034Sdougm * 3284653Sdougm * Check to see if the specified prop is valid for this protocol. 3293034Sdougm */ 3303034Sdougm 3313034Sdougm int 3326214Sdougm sa_proto_valid_prop(sa_handle_t handle, char *proto, sa_property_t prop, 3336214Sdougm sa_optionset_t opt) 3343034Sdougm { 3353034Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 3363034Sdougm int ret = 0; 3373034Sdougm 3383034Sdougm if (ops != NULL && ops->sa_valid_prop != NULL) 3396214Sdougm ret = ops->sa_valid_prop(handle, prop, opt); 3403034Sdougm return (ret); 3413034Sdougm } 3423034Sdougm 3433034Sdougm /* 3443034Sdougm * sa_proto_valid_space(proto, space) 3453034Sdougm * 3464653Sdougm * Check if space is valid optionspace for proto. 3473034Sdougm * Protocols that don't implement this don't support spaces. 3483034Sdougm */ 3493034Sdougm int 3503034Sdougm sa_proto_valid_space(char *proto, char *token) 3513034Sdougm { 3523034Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 3533034Sdougm int ret = 0; 3543034Sdougm 3553034Sdougm if (ops != NULL && ops->sa_valid_space != NULL) 3564653Sdougm ret = ops->sa_valid_space(token); 3573034Sdougm return (ret); 3583034Sdougm } 3593034Sdougm 3603034Sdougm /* 3613034Sdougm * sa_proto_space_alias(proto, space) 3623034Sdougm * 3634653Sdougm * If the name for space is an alias, return its proper name. This is 3643034Sdougm * used to translate "default" values into proper form. 3653034Sdougm */ 3663034Sdougm char * 3673034Sdougm sa_proto_space_alias(char *proto, char *space) 3683034Sdougm { 3693034Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 3703034Sdougm char *ret = space; 3713034Sdougm 3723034Sdougm if (ops != NULL && ops->sa_space_alias != NULL) 3734653Sdougm ret = ops->sa_space_alias(space); 3743034Sdougm return (ret); 3753034Sdougm } 3763034Sdougm 3773034Sdougm /* 3783034Sdougm * sa_proto_security_prop(proto, token) 3793034Sdougm * 3803034Sdougm * Check to see if the property name in token is a valid named 3813034Sdougm * optionset property. 3823034Sdougm */ 3833034Sdougm 3843034Sdougm int 3853034Sdougm sa_proto_security_prop(char *proto, char *token) 3863034Sdougm { 3873034Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 3883034Sdougm int ret = 0; 3893034Sdougm 3903034Sdougm if (ops != NULL && ops->sa_security_prop != NULL) 3914653Sdougm ret = ops->sa_security_prop(token); 3923034Sdougm return (ret); 3933034Sdougm } 3943034Sdougm 3953034Sdougm /* 3963034Sdougm * sa_proto_legacy_opts(proto, grouup, options) 3973034Sdougm * 3983034Sdougm * Have the protocol specific parser parse the options string and add 3993034Sdougm * an appropriate optionset to group. 4003034Sdougm */ 4013034Sdougm 4023034Sdougm int 4033034Sdougm sa_proto_legacy_opts(char *proto, sa_group_t group, char *options) 4043034Sdougm { 4053034Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 4063034Sdougm int ret = SA_INVALID_PROTOCOL; 4073034Sdougm 4083034Sdougm if (ops != NULL && ops->sa_legacy_opts != NULL) 4094653Sdougm ret = ops->sa_legacy_opts(group, options); 4103034Sdougm return (ret); 4113034Sdougm } 4123034Sdougm 4133034Sdougm /* 4143034Sdougm * sa_proto_legacy_format(proto, group, hier) 4153034Sdougm * 4163034Sdougm * Return a legacy format string representing either the group's 4173034Sdougm * properties or the groups hierarchical properties. 4183034Sdougm */ 4193034Sdougm 4203034Sdougm char * 4213034Sdougm sa_proto_legacy_format(char *proto, sa_group_t group, int hier) 4223034Sdougm { 4233034Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 4243034Sdougm char *ret = NULL; 4253034Sdougm 4263034Sdougm if (ops != NULL && ops->sa_legacy_format != NULL) 4274653Sdougm ret = ops->sa_legacy_format(group, hier); 4283034Sdougm return (ret); 4293034Sdougm } 4303034Sdougm 4313034Sdougm void 4323034Sdougm sa_format_free(char *str) 4333034Sdougm { 4343034Sdougm free(str); 4353034Sdougm } 4363034Sdougm 4373034Sdougm /* 4383034Sdougm * sharectl related API functions 4393034Sdougm */ 4403034Sdougm 4413034Sdougm /* 4423034Sdougm * sa_proto_get_properties(proto) 4433034Sdougm * 4443034Sdougm * Return the set of properties that are specific to the 4453034Sdougm * protocol. These are usually in /etc/dfs/<proto> and related files, 4463034Sdougm * but only the protocol module knows which ones for sure. 4473034Sdougm */ 4483034Sdougm 4493034Sdougm sa_protocol_properties_t 4503034Sdougm sa_proto_get_properties(char *proto) 4513034Sdougm { 4523034Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 4533034Sdougm sa_protocol_properties_t props = NULL; 4543034Sdougm 4553034Sdougm if (ops != NULL && ops->sa_get_proto_set != NULL) 4564653Sdougm props = ops->sa_get_proto_set(); 4573034Sdougm return (props); 4583034Sdougm } 4593034Sdougm 4603034Sdougm /* 4613034Sdougm * sa_proto_set_property(proto, prop) 4623034Sdougm * 4635331Samw * Update the protocol specific property. 4643034Sdougm */ 4653034Sdougm 4663034Sdougm int 4673034Sdougm sa_proto_set_property(char *proto, sa_property_t prop) 4683034Sdougm { 4693034Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 4703034Sdougm int ret = SA_OK; 4714653Sdougm 4723034Sdougm if (ops != NULL && ops->sa_set_proto_prop != NULL) 4734653Sdougm ret = ops->sa_set_proto_prop(prop); 4743034Sdougm return (ret); 4753034Sdougm } 4763034Sdougm 4773034Sdougm /* 4783034Sdougm * sa_valid_protocol(proto) 4793034Sdougm * 4804653Sdougm * Check to see if the protocol specified is defined by a 4813034Sdougm * plugin. Returns true (1) or false (0) 4823034Sdougm */ 4833034Sdougm 4843034Sdougm int 4853034Sdougm sa_valid_protocol(char *proto) 4863034Sdougm { 4873034Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 4883034Sdougm return (ops != NULL); 4893034Sdougm } 4903034Sdougm 4913034Sdougm /* 4923034Sdougm * Return the current operational status of the protocol 4933034Sdougm */ 4943034Sdougm 4953034Sdougm char * 4963034Sdougm sa_get_protocol_status(char *proto) 4973034Sdougm { 4983034Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 4993034Sdougm char *ret = NULL; 5003034Sdougm if (ops != NULL && ops->sa_get_proto_status != NULL) 5014653Sdougm ret = ops->sa_get_proto_status(proto); 5023034Sdougm return (ret); 5033034Sdougm } 5043034Sdougm 5053034Sdougm /* 5063034Sdougm * sa_proto_update_legacy(proto, share) 5073034Sdougm * 5083034Sdougm * Update the protocol specific legacy files if necessary for the 5093034Sdougm * specified share. 5103034Sdougm */ 5113034Sdougm 5123034Sdougm int 5133034Sdougm sa_proto_update_legacy(char *proto, sa_share_t share) 5143034Sdougm { 5153034Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 5163034Sdougm int ret = SA_NOT_IMPLEMENTED; 5173034Sdougm 5183034Sdougm if (ops != NULL) { 5194653Sdougm if (ops->sa_update_legacy != NULL) 5204653Sdougm ret = ops->sa_update_legacy(share); 5213034Sdougm } 5223034Sdougm return (ret); 5233034Sdougm } 5243034Sdougm 5253034Sdougm /* 5263034Sdougm * sa_delete_legacy(proto, share) 5273034Sdougm * 5284653Sdougm * Remove the specified share from the protocol specific legacy files. 5293034Sdougm */ 5303034Sdougm 5313034Sdougm int 5323034Sdougm sa_proto_delete_legacy(char *proto, sa_share_t share) 5333034Sdougm { 5343034Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 5355331Samw int ret = SA_NOT_IMPLEMENTED; 5363034Sdougm 5373034Sdougm if (ops != NULL) { 5384653Sdougm if (ops->sa_delete_legacy != NULL) 5394653Sdougm ret = ops->sa_delete_legacy(share); 5406007Sthurlow } else { 5416007Sthurlow if (proto != NULL) 5426007Sthurlow ret = SA_NOT_IMPLEMENTED; 5436007Sthurlow else 5446007Sthurlow ret = SA_INVALID_PROTOCOL; 5456007Sthurlow } 5466007Sthurlow return (ret); 5476007Sthurlow } 5486007Sthurlow 5496007Sthurlow /* 5506007Sthurlow * sa_proto_delete_section(proto, section) 5516007Sthurlow * 5526007Sthurlow * Remove the specified section from the protocol specific legacy files, 5536007Sthurlow * if supported. 5546007Sthurlow */ 5556007Sthurlow 5566007Sthurlow int 5576007Sthurlow sa_proto_delete_section(char *proto, char *section) 5586007Sthurlow { 5596007Sthurlow struct sa_plugin_ops *ops = find_protocol(proto); 5606007Sthurlow int ret = SA_OK; 5616007Sthurlow 5626007Sthurlow if (ops != NULL) { 5636007Sthurlow if (ops->sa_delete_proto_section != NULL) 5646007Sthurlow ret = ops->sa_delete_proto_section(section); 5656007Sthurlow } else { 5666007Sthurlow if (proto != NULL) 5676007Sthurlow ret = SA_NOT_IMPLEMENTED; 5686007Sthurlow else 5696007Sthurlow ret = SA_INVALID_PROTOCOL; 5705331Samw } 5715331Samw return (ret); 5725331Samw } 5735331Samw 5745331Samw /* 5755331Samw * sa_proto_change_notify(share, char *protocol) 5765331Samw * 5775331Samw * Notify the protocol that a change has been made to the share 5785331Samw */ 5795331Samw 5805331Samw int 5815331Samw sa_proto_change_notify(sa_share_t share, char *proto) 5825331Samw { 5835331Samw struct sa_plugin_ops *ops = find_protocol(proto); 5845331Samw int ret = SA_NOT_IMPLEMENTED; 5855331Samw 5865331Samw if (ops != NULL) { 5875331Samw if (ops->sa_change_notify != NULL) 5885331Samw ret = ops->sa_change_notify(share); 5895331Samw } else if (proto == NULL) { 5906007Sthurlow 5915331Samw ret = SA_INVALID_PROTOCOL; 5925331Samw } 5935331Samw return (ret); 5945331Samw } 5955331Samw 5965331Samw /* 5975331Samw * sa_proto_notify_resource(resource, char *protocol) 5985331Samw * 5995331Samw * Notify the protocol that a change has been made to the share 6005331Samw */ 6015331Samw 6025331Samw int 6035331Samw sa_proto_notify_resource(sa_resource_t resource, 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_notify_resource != NULL) 6105331Samw ret = ops->sa_notify_resource(resource); 6115331Samw } else if (proto == NULL) { 6124653Sdougm ret = SA_INVALID_PROTOCOL; 6133034Sdougm } 6143034Sdougm return (ret); 6153034Sdougm } 6165331Samw 6175331Samw /* 6185331Samw * sa_proto_get_featureset(protocol) 6195331Samw * 6205331Samw * Get bitmask of defined features of the protocol. These are 6215331Samw * primarily things like SA_FEATURE_RESOURCE (shares are by resource 6225331Samw * name rather than path) and other operational features that affect 6235331Samw * behavior. 6245331Samw */ 6255331Samw 6265331Samw uint64_t 6275331Samw sa_proto_get_featureset(char *proto) 6285331Samw { 6295331Samw struct sa_plugin_ops *ops = find_protocol(proto); 6305331Samw uint64_t ret = 0; 6315331Samw 6325331Samw if (ops != NULL) { 6335331Samw if (ops->sa_features != NULL) 6345331Samw ret = ops->sa_features(); 6355331Samw } 6365331Samw /* if not implemented, zero is valid */ 6375331Samw return (ret); 6385331Samw } 6395331Samw 6405331Samw /* 6415331Samw * sa_proto_get_transients(sa_handle_t) 6425331Samw * 6435331Samw * Called to get any protocol specific transient shares. NFS doesn't 6445331Samw * use this since the info is in sharetab which is processed as a 6455331Samw * common transient store. 6465331Samw * 6475331Samw * The protocol plugin should verify that the share isn't in the 6485331Samw * repository and then add it as a transient. 6495331Samw * 6505331Samw * Not having an entry is not a problem. It returns 0 in that case. 6515331Samw */ 6525331Samw 6535331Samw int 6545331Samw sa_proto_get_transients(sa_handle_t handle, char *proto) 6555331Samw { 6565331Samw struct sa_plugin_ops *ops = find_protocol(proto); 6575331Samw int ret = 0; 6585331Samw 6595331Samw if (ops != NULL) { 6605331Samw if (ops->sa_get_transient_shares != NULL) 6615331Samw ret = ops->sa_get_transient_shares(handle); 6625331Samw } 6635331Samw return (ret); 6645331Samw } 6655331Samw 6665331Samw /* 6675331Samw * sa_proto_rename_resource(sa_handle_t, proto, sa_resource_t, newname) 6685331Samw * 6695331Samw * Protocols may need to know when a resource has changed names in 6705331Samw * order to notify clients. This must be done "before" the name in the 6715331Samw * resource has been changed. Not being implemented is not a problem. 6725331Samw */ 6735331Samw 6745331Samw int 6755331Samw sa_proto_rename_resource(sa_handle_t handle, char *proto, 6765331Samw sa_resource_t resource, char *newname) 6775331Samw { 6785331Samw struct sa_plugin_ops *ops = find_protocol(proto); 6795331Samw int ret = SA_OK; 6805331Samw 6815331Samw if (ops != NULL) { 6825331Samw if (ops->sa_rename_resource != NULL) 6835331Samw ret = ops->sa_rename_resource(handle, resource, 6845331Samw newname); 6855331Samw } 6865331Samw return (ret); 6875331Samw } 688