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> 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 /* 593034Sdougm * proto_plugin_init() 603034Sdougm * 613034Sdougm * Initialize the protocol specific plugin modules. 623034Sdougm * 633034Sdougm * Walk /usr/lib/fs/\* for libshare_*.so modules. That is, 643034Sdougm * /usr/lib/fs/nfs/libshare_nfs.so. The protocol specific directory 653034Sdougm * would have a modules with name libshare_<proto>.so. If one is 663034Sdougm * found, initialize it and add to the internal list of 675331Samw * protocols. These are used for protocol specific operations. 683034Sdougm */ 693034Sdougm 703034Sdougm int 713034Sdougm proto_plugin_init() 723034Sdougm { 733034Sdougm struct sa_proto_plugin *proto; 743034Sdougm int num_protos = 0; 753034Sdougm int err; 763034Sdougm struct sa_plugin_ops *plugin_ops; 773034Sdougm void *dlhandle; 783034Sdougm DIR *dir; 793034Sdougm struct dirent *dent; 803034Sdougm int ret = SA_OK; 813034Sdougm struct stat st; 823034Sdougm 833034Sdougm /* 844653Sdougm * Should walk "/usr/lib/fs/" for files of the form: 853034Sdougm * libshare_*.so 863034Sdougm */ 873034Sdougm dir = opendir(SA_LIB_DIR); 883034Sdougm if (dir != NULL) { 894653Sdougm while (ret == SA_OK && (dent = readdir(dir)) != NULL) { 904653Sdougm char path[MAXPATHLEN]; 914653Sdougm char isa[MAXISALEN]; 923910Sdougm 933910Sdougm #if defined(_LP64) 944653Sdougm if (sysinfo(SI_ARCHITECTURE_64, isa, MAXISALEN) == -1) 954653Sdougm isa[0] = '\0'; 963910Sdougm #else 974653Sdougm isa[0] = '\0'; 983910Sdougm #endif 994653Sdougm (void) snprintf(path, MAXPATHLEN, 1004653Sdougm "%s/%s/%s/libshare_%s.so.1", SA_LIB_DIR, 1014653Sdougm dent->d_name, isa, dent->d_name); 1024653Sdougm /* 1034653Sdougm * If file doesn't exist, don't try to map it 1044653Sdougm */ 1054653Sdougm if (stat(path, &st) < 0) 1064653Sdougm continue; 1074653Sdougm 1084653Sdougm dlhandle = dlopen(path, RTLD_FIRST|RTLD_LAZY); 1094653Sdougm if (dlhandle != NULL) { 1104653Sdougm plugin_ops = (struct sa_plugin_ops *) 1114653Sdougm dlsym(dlhandle, "sa_plugin_ops"); 1124653Sdougm proto = (struct sa_proto_plugin *) 1134653Sdougm calloc(1, sizeof (struct sa_proto_plugin)); 1144653Sdougm if (proto != NULL) { 1154653Sdougm proto->plugin_ops = plugin_ops; 1164653Sdougm proto->plugin_handle = dlhandle; 1174653Sdougm num_protos++; 1184653Sdougm proto->plugin_next = sap_proto_list; 1194653Sdougm sap_proto_list = proto; 1204653Sdougm } else { 1214653Sdougm ret = SA_NO_MEMORY; 1224653Sdougm } 1234653Sdougm } else { 1244653Sdougm (void) fprintf(stderr, 1254653Sdougm dgettext(TEXT_DOMAIN, 1264653Sdougm "Error in plugin for protocol %s: %s\n"), 1274653Sdougm dent->d_name, dlerror()); 1284653Sdougm } 1293034Sdougm } 1304653Sdougm (void) closedir(dir); 1313034Sdougm } 1323034Sdougm if (ret == SA_OK) { 1334653Sdougm sa_proto_handle.sa_proto = 1344653Sdougm (char **)calloc(num_protos, sizeof (char *)); 1354653Sdougm sa_proto_handle.sa_ops = 1364653Sdougm (struct sa_plugin_ops **)calloc(num_protos, 1374653Sdougm sizeof (struct sa_plugin_ops *)); 1384653Sdougm if (sa_proto_handle.sa_proto != NULL && 1394653Sdougm sa_proto_handle.sa_ops != NULL) { 1404653Sdougm int i; 1414653Sdougm struct sa_proto_plugin *tmp; 1424653Sdougm 1434653Sdougm for (i = 0, tmp = sap_proto_list; 1446162Sdougm i < num_protos && tmp != NULL; 1454653Sdougm tmp = tmp->plugin_next) { 1464653Sdougm err = 0; 1474653Sdougm if (tmp->plugin_ops->sa_init != NULL) 1484653Sdougm err = tmp->plugin_ops->sa_init(); 1494653Sdougm if (err == SA_OK) { 1504653Sdougm /* 1514653Sdougm * Only include if the init 1524653Sdougm * succeeded or was NULL 1534653Sdougm */ 1544653Sdougm sa_proto_handle.sa_num_proto++; 1554653Sdougm sa_proto_handle.sa_ops[i] = 1564653Sdougm tmp->plugin_ops; 1574653Sdougm sa_proto_handle.sa_proto[i] = 1584653Sdougm tmp->plugin_ops->sa_protocol; 1594653Sdougm i++; 1604653Sdougm } 1614653Sdougm } 1623034Sdougm } 1633034Sdougm } else { 1644653Sdougm /* 1654653Sdougm * There was an error, so cleanup prior to return of failure. 1664653Sdougm */ 1674653Sdougm proto_plugin_fini(); 1683034Sdougm } 1693034Sdougm return (ret); 1703034Sdougm } 1713034Sdougm 1723034Sdougm /* 1733034Sdougm * proto_plugin_fini() 1743034Sdougm * 1754653Sdougm * Uninitialize all the plugin modules. 1763034Sdougm */ 1773034Sdougm 1783034Sdougm void 1793034Sdougm proto_plugin_fini() 1803034Sdougm { 1813034Sdougm /* 1824653Sdougm * Free up all the protocols, calling their fini, if there is 1833034Sdougm * one. 1843034Sdougm */ 1853034Sdougm while (sap_proto_list != NULL) { 1864653Sdougm struct sa_proto_plugin *next; 1874653Sdougm 1884653Sdougm next = sap_proto_list->plugin_next; 1894653Sdougm sap_proto_list->plugin_ops->sa_fini(); 1904653Sdougm if (sap_proto_list->plugin_handle != NULL) 1914653Sdougm (void) dlclose(sap_proto_list->plugin_handle); 1924653Sdougm free(sap_proto_list); 1934653Sdougm sap_proto_list = next; 1943034Sdougm } 1953034Sdougm if (sa_proto_handle.sa_ops != NULL) { 1964653Sdougm free(sa_proto_handle.sa_ops); 1974653Sdougm sa_proto_handle.sa_ops = NULL; 1983034Sdougm } 1993034Sdougm if (sa_proto_handle.sa_proto != NULL) { 2004653Sdougm free(sa_proto_handle.sa_proto); 2014653Sdougm sa_proto_handle.sa_proto = NULL; 2023034Sdougm } 2033034Sdougm sa_proto_handle.sa_num_proto = 0; 2043034Sdougm } 2053034Sdougm 2063034Sdougm /* 2073034Sdougm * find_protocol(proto) 2083034Sdougm * 2093034Sdougm * Search the plugin list for the specified protocol and return the 2103034Sdougm * ops vector. NULL if protocol is not defined. 2113034Sdougm */ 2123034Sdougm 2133034Sdougm static struct sa_plugin_ops * 2143034Sdougm find_protocol(char *proto) 2153034Sdougm { 2163034Sdougm int i; 2173034Sdougm 2183034Sdougm if (proto != NULL) { 2194653Sdougm for (i = 0; i < sa_proto_handle.sa_num_proto; i++) { 2204653Sdougm if (strcmp(proto, sa_proto_handle.sa_proto[i]) == 0) 2214653Sdougm return (sa_proto_handle.sa_ops[i]); 2224653Sdougm } 2233034Sdougm } 2243034Sdougm return (NULL); 2253034Sdougm } 2263034Sdougm 2273034Sdougm /* 2283034Sdougm * sa_proto_share(proto, share) 2293034Sdougm * 2303034Sdougm * Activate a share for the specified protocol. 2313034Sdougm */ 2323034Sdougm 2333034Sdougm int 2343034Sdougm sa_proto_share(char *proto, sa_share_t share) 2353034Sdougm { 2363034Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 2373034Sdougm int ret = SA_INVALID_PROTOCOL; 2383034Sdougm 2393034Sdougm if (ops != NULL && ops->sa_share != NULL) 2404653Sdougm ret = ops->sa_share(share); 2413034Sdougm return (ret); 2423034Sdougm } 2433034Sdougm 2443034Sdougm /* 2455331Samw * sa_proto_unshare(proto, share) 2463034Sdougm * 2475331Samw * Deactivate (unshare) the share for this protocol. 2483034Sdougm */ 2493034Sdougm 2503034Sdougm int 2514543Smarks sa_proto_unshare(sa_share_t share, char *proto, char *path) 2523034Sdougm { 2533034Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 2543034Sdougm int ret = SA_INVALID_PROTOCOL; 2553034Sdougm 2563034Sdougm if (ops != NULL && ops->sa_unshare != NULL) 2574653Sdougm ret = ops->sa_unshare(share, path); 2583034Sdougm return (ret); 2593034Sdougm } 2603034Sdougm 2613034Sdougm /* 2625331Samw * sa_proto_share_resource(char *proto, sa_resource_t resource) 2635331Samw * 2645331Samw * For protocols that actually enable at the resource level, do the 2655331Samw * protocol specific resource enable. If it doesn't, return an error. 2665331Samw * Note that the resource functions are optional so can return 2675331Samw * SA_NOT_SUPPORTED. 2685331Samw */ 2695331Samw 2705331Samw int 2715331Samw sa_proto_share_resource(char *proto, sa_resource_t resource) 2725331Samw { 2735331Samw struct sa_plugin_ops *ops = find_protocol(proto); 2745331Samw int ret = SA_INVALID_PROTOCOL; 2755331Samw 2765331Samw if (ops != NULL) { 2775331Samw if (ops->sa_enable_resource != NULL) 2785331Samw ret = ops->sa_enable_resource(resource); 2795331Samw else 2805331Samw ret = SA_NOT_SUPPORTED; 2815331Samw } 2825331Samw return (ret); 2835331Samw } 2845331Samw 2855331Samw /* 2865331Samw * sa_proto_unshare_resource(char *proto, sa_resource_t resource) 2875331Samw * 2885331Samw * For protocols that actually disable at the resource level, do the 2895331Samw * protocol specific resource disable. If it doesn't, return an error. 2905331Samw */ 2915331Samw 2925331Samw int 2935331Samw sa_proto_unshare_resource(char *proto, sa_resource_t resource) 2945331Samw { 2955331Samw struct sa_plugin_ops *ops = find_protocol(proto); 2965331Samw int ret = SA_INVALID_PROTOCOL; 2975331Samw 2985331Samw if (ops != NULL) { 2995331Samw if (ops->sa_disable_resource != NULL) 3005331Samw ret = ops->sa_disable_resource(resource); 3015331Samw else 3025331Samw ret = SA_NOT_SUPPORTED; 3035331Samw } 3045331Samw return (ret); 3055331Samw } 3065331Samw 3075331Samw /* 308*6214Sdougm * sa_proto_valid_prop(handle, proto, prop, opt) 3093034Sdougm * 3104653Sdougm * Check to see if the specified prop is valid for this protocol. 3113034Sdougm */ 3123034Sdougm 3133034Sdougm int 314*6214Sdougm sa_proto_valid_prop(sa_handle_t handle, char *proto, sa_property_t prop, 315*6214Sdougm sa_optionset_t opt) 3163034Sdougm { 3173034Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 3183034Sdougm int ret = 0; 3193034Sdougm 3203034Sdougm if (ops != NULL && ops->sa_valid_prop != NULL) 321*6214Sdougm ret = ops->sa_valid_prop(handle, prop, opt); 3223034Sdougm return (ret); 3233034Sdougm } 3243034Sdougm 3253034Sdougm /* 3263034Sdougm * sa_proto_valid_space(proto, space) 3273034Sdougm * 3284653Sdougm * Check if space is valid optionspace for proto. 3293034Sdougm * Protocols that don't implement this don't support spaces. 3303034Sdougm */ 3313034Sdougm int 3323034Sdougm sa_proto_valid_space(char *proto, char *token) 3333034Sdougm { 3343034Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 3353034Sdougm int ret = 0; 3363034Sdougm 3373034Sdougm if (ops != NULL && ops->sa_valid_space != NULL) 3384653Sdougm ret = ops->sa_valid_space(token); 3393034Sdougm return (ret); 3403034Sdougm } 3413034Sdougm 3423034Sdougm /* 3433034Sdougm * sa_proto_space_alias(proto, space) 3443034Sdougm * 3454653Sdougm * If the name for space is an alias, return its proper name. This is 3463034Sdougm * used to translate "default" values into proper form. 3473034Sdougm */ 3483034Sdougm char * 3493034Sdougm sa_proto_space_alias(char *proto, char *space) 3503034Sdougm { 3513034Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 3523034Sdougm char *ret = space; 3533034Sdougm 3543034Sdougm if (ops != NULL && ops->sa_space_alias != NULL) 3554653Sdougm ret = ops->sa_space_alias(space); 3563034Sdougm return (ret); 3573034Sdougm } 3583034Sdougm 3593034Sdougm /* 3603034Sdougm * sa_proto_security_prop(proto, token) 3613034Sdougm * 3623034Sdougm * Check to see if the property name in token is a valid named 3633034Sdougm * optionset property. 3643034Sdougm */ 3653034Sdougm 3663034Sdougm int 3673034Sdougm sa_proto_security_prop(char *proto, char *token) 3683034Sdougm { 3693034Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 3703034Sdougm int ret = 0; 3713034Sdougm 3723034Sdougm if (ops != NULL && ops->sa_security_prop != NULL) 3734653Sdougm ret = ops->sa_security_prop(token); 3743034Sdougm return (ret); 3753034Sdougm } 3763034Sdougm 3773034Sdougm /* 3783034Sdougm * sa_proto_legacy_opts(proto, grouup, options) 3793034Sdougm * 3803034Sdougm * Have the protocol specific parser parse the options string and add 3813034Sdougm * an appropriate optionset to group. 3823034Sdougm */ 3833034Sdougm 3843034Sdougm int 3853034Sdougm sa_proto_legacy_opts(char *proto, sa_group_t group, char *options) 3863034Sdougm { 3873034Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 3883034Sdougm int ret = SA_INVALID_PROTOCOL; 3893034Sdougm 3903034Sdougm if (ops != NULL && ops->sa_legacy_opts != NULL) 3914653Sdougm ret = ops->sa_legacy_opts(group, options); 3923034Sdougm return (ret); 3933034Sdougm } 3943034Sdougm 3953034Sdougm /* 3963034Sdougm * sa_proto_legacy_format(proto, group, hier) 3973034Sdougm * 3983034Sdougm * Return a legacy format string representing either the group's 3993034Sdougm * properties or the groups hierarchical properties. 4003034Sdougm */ 4013034Sdougm 4023034Sdougm char * 4033034Sdougm sa_proto_legacy_format(char *proto, sa_group_t group, int hier) 4043034Sdougm { 4053034Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 4063034Sdougm char *ret = NULL; 4073034Sdougm 4083034Sdougm if (ops != NULL && ops->sa_legacy_format != NULL) 4094653Sdougm ret = ops->sa_legacy_format(group, hier); 4103034Sdougm return (ret); 4113034Sdougm } 4123034Sdougm 4133034Sdougm void 4143034Sdougm sa_format_free(char *str) 4153034Sdougm { 4163034Sdougm free(str); 4173034Sdougm } 4183034Sdougm 4193034Sdougm /* 4203034Sdougm * sharectl related API functions 4213034Sdougm */ 4223034Sdougm 4233034Sdougm /* 4243034Sdougm * sa_proto_get_properties(proto) 4253034Sdougm * 4263034Sdougm * Return the set of properties that are specific to the 4273034Sdougm * protocol. These are usually in /etc/dfs/<proto> and related files, 4283034Sdougm * but only the protocol module knows which ones for sure. 4293034Sdougm */ 4303034Sdougm 4313034Sdougm sa_protocol_properties_t 4323034Sdougm sa_proto_get_properties(char *proto) 4333034Sdougm { 4343034Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 4353034Sdougm sa_protocol_properties_t props = NULL; 4363034Sdougm 4373034Sdougm if (ops != NULL && ops->sa_get_proto_set != NULL) 4384653Sdougm props = ops->sa_get_proto_set(); 4393034Sdougm return (props); 4403034Sdougm } 4413034Sdougm 4423034Sdougm /* 4433034Sdougm * sa_proto_set_property(proto, prop) 4443034Sdougm * 4455331Samw * Update the protocol specific property. 4463034Sdougm */ 4473034Sdougm 4483034Sdougm int 4493034Sdougm sa_proto_set_property(char *proto, sa_property_t prop) 4503034Sdougm { 4513034Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 4523034Sdougm int ret = SA_OK; 4534653Sdougm 4543034Sdougm if (ops != NULL && ops->sa_set_proto_prop != NULL) 4554653Sdougm ret = ops->sa_set_proto_prop(prop); 4563034Sdougm return (ret); 4573034Sdougm } 4583034Sdougm 4593034Sdougm /* 4603034Sdougm * sa_valid_protocol(proto) 4613034Sdougm * 4624653Sdougm * Check to see if the protocol specified is defined by a 4633034Sdougm * plugin. Returns true (1) or false (0) 4643034Sdougm */ 4653034Sdougm 4663034Sdougm int 4673034Sdougm sa_valid_protocol(char *proto) 4683034Sdougm { 4693034Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 4703034Sdougm return (ops != NULL); 4713034Sdougm } 4723034Sdougm 4733034Sdougm /* 4743034Sdougm * Return the current operational status of the protocol 4753034Sdougm */ 4763034Sdougm 4773034Sdougm char * 4783034Sdougm sa_get_protocol_status(char *proto) 4793034Sdougm { 4803034Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 4813034Sdougm char *ret = NULL; 4823034Sdougm if (ops != NULL && ops->sa_get_proto_status != NULL) 4834653Sdougm ret = ops->sa_get_proto_status(proto); 4843034Sdougm return (ret); 4853034Sdougm } 4863034Sdougm 4873034Sdougm /* 4883034Sdougm * sa_proto_update_legacy(proto, share) 4893034Sdougm * 4903034Sdougm * Update the protocol specific legacy files if necessary for the 4913034Sdougm * specified share. 4923034Sdougm */ 4933034Sdougm 4943034Sdougm int 4953034Sdougm sa_proto_update_legacy(char *proto, sa_share_t share) 4963034Sdougm { 4973034Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 4983034Sdougm int ret = SA_NOT_IMPLEMENTED; 4993034Sdougm 5003034Sdougm if (ops != NULL) { 5014653Sdougm if (ops->sa_update_legacy != NULL) 5024653Sdougm ret = ops->sa_update_legacy(share); 5033034Sdougm } 5043034Sdougm return (ret); 5053034Sdougm } 5063034Sdougm 5073034Sdougm /* 5083034Sdougm * sa_delete_legacy(proto, share) 5093034Sdougm * 5104653Sdougm * Remove the specified share from the protocol specific legacy files. 5113034Sdougm */ 5123034Sdougm 5133034Sdougm int 5143034Sdougm sa_proto_delete_legacy(char *proto, sa_share_t share) 5153034Sdougm { 5163034Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 5175331Samw int ret = SA_NOT_IMPLEMENTED; 5183034Sdougm 5193034Sdougm if (ops != NULL) { 5204653Sdougm if (ops->sa_delete_legacy != NULL) 5214653Sdougm ret = ops->sa_delete_legacy(share); 5226007Sthurlow } else { 5236007Sthurlow if (proto != NULL) 5246007Sthurlow ret = SA_NOT_IMPLEMENTED; 5256007Sthurlow else 5266007Sthurlow ret = SA_INVALID_PROTOCOL; 5276007Sthurlow } 5286007Sthurlow return (ret); 5296007Sthurlow } 5306007Sthurlow 5316007Sthurlow /* 5326007Sthurlow * sa_proto_delete_section(proto, section) 5336007Sthurlow * 5346007Sthurlow * Remove the specified section from the protocol specific legacy files, 5356007Sthurlow * if supported. 5366007Sthurlow */ 5376007Sthurlow 5386007Sthurlow int 5396007Sthurlow sa_proto_delete_section(char *proto, char *section) 5406007Sthurlow { 5416007Sthurlow struct sa_plugin_ops *ops = find_protocol(proto); 5426007Sthurlow int ret = SA_OK; 5436007Sthurlow 5446007Sthurlow if (ops != NULL) { 5456007Sthurlow if (ops->sa_delete_proto_section != NULL) 5466007Sthurlow ret = ops->sa_delete_proto_section(section); 5476007Sthurlow } else { 5486007Sthurlow if (proto != NULL) 5496007Sthurlow ret = SA_NOT_IMPLEMENTED; 5506007Sthurlow else 5516007Sthurlow ret = SA_INVALID_PROTOCOL; 5525331Samw } 5535331Samw return (ret); 5545331Samw } 5555331Samw 5565331Samw /* 5575331Samw * sa_proto_change_notify(share, char *protocol) 5585331Samw * 5595331Samw * Notify the protocol that a change has been made to the share 5605331Samw */ 5615331Samw 5625331Samw int 5635331Samw sa_proto_change_notify(sa_share_t share, char *proto) 5645331Samw { 5655331Samw struct sa_plugin_ops *ops = find_protocol(proto); 5665331Samw int ret = SA_NOT_IMPLEMENTED; 5675331Samw 5685331Samw if (ops != NULL) { 5695331Samw if (ops->sa_change_notify != NULL) 5705331Samw ret = ops->sa_change_notify(share); 5715331Samw } else if (proto == NULL) { 5726007Sthurlow 5735331Samw ret = SA_INVALID_PROTOCOL; 5745331Samw } 5755331Samw return (ret); 5765331Samw } 5775331Samw 5785331Samw /* 5795331Samw * sa_proto_notify_resource(resource, char *protocol) 5805331Samw * 5815331Samw * Notify the protocol that a change has been made to the share 5825331Samw */ 5835331Samw 5845331Samw int 5855331Samw sa_proto_notify_resource(sa_resource_t resource, char *proto) 5865331Samw { 5875331Samw struct sa_plugin_ops *ops = find_protocol(proto); 5885331Samw int ret = SA_NOT_IMPLEMENTED; 5895331Samw 5905331Samw if (ops != NULL) { 5915331Samw if (ops->sa_notify_resource != NULL) 5925331Samw ret = ops->sa_notify_resource(resource); 5935331Samw } else if (proto == NULL) { 5944653Sdougm ret = SA_INVALID_PROTOCOL; 5953034Sdougm } 5963034Sdougm return (ret); 5973034Sdougm } 5985331Samw 5995331Samw /* 6005331Samw * sa_proto_get_featureset(protocol) 6015331Samw * 6025331Samw * Get bitmask of defined features of the protocol. These are 6035331Samw * primarily things like SA_FEATURE_RESOURCE (shares are by resource 6045331Samw * name rather than path) and other operational features that affect 6055331Samw * behavior. 6065331Samw */ 6075331Samw 6085331Samw uint64_t 6095331Samw sa_proto_get_featureset(char *proto) 6105331Samw { 6115331Samw struct sa_plugin_ops *ops = find_protocol(proto); 6125331Samw uint64_t ret = 0; 6135331Samw 6145331Samw if (ops != NULL) { 6155331Samw if (ops->sa_features != NULL) 6165331Samw ret = ops->sa_features(); 6175331Samw } 6185331Samw /* if not implemented, zero is valid */ 6195331Samw return (ret); 6205331Samw } 6215331Samw 6225331Samw /* 6235331Samw * sa_proto_get_transients(sa_handle_t) 6245331Samw * 6255331Samw * Called to get any protocol specific transient shares. NFS doesn't 6265331Samw * use this since the info is in sharetab which is processed as a 6275331Samw * common transient store. 6285331Samw * 6295331Samw * The protocol plugin should verify that the share isn't in the 6305331Samw * repository and then add it as a transient. 6315331Samw * 6325331Samw * Not having an entry is not a problem. It returns 0 in that case. 6335331Samw */ 6345331Samw 6355331Samw int 6365331Samw sa_proto_get_transients(sa_handle_t handle, char *proto) 6375331Samw { 6385331Samw struct sa_plugin_ops *ops = find_protocol(proto); 6395331Samw int ret = 0; 6405331Samw 6415331Samw if (ops != NULL) { 6425331Samw if (ops->sa_get_transient_shares != NULL) 6435331Samw ret = ops->sa_get_transient_shares(handle); 6445331Samw } 6455331Samw return (ret); 6465331Samw } 6475331Samw 6485331Samw /* 6495331Samw * sa_proto_rename_resource(sa_handle_t, proto, sa_resource_t, newname) 6505331Samw * 6515331Samw * Protocols may need to know when a resource has changed names in 6525331Samw * order to notify clients. This must be done "before" the name in the 6535331Samw * resource has been changed. Not being implemented is not a problem. 6545331Samw */ 6555331Samw 6565331Samw int 6575331Samw sa_proto_rename_resource(sa_handle_t handle, char *proto, 6585331Samw sa_resource_t resource, char *newname) 6595331Samw { 6605331Samw struct sa_plugin_ops *ops = find_protocol(proto); 6615331Samw int ret = SA_OK; 6625331Samw 6635331Samw if (ops != NULL) { 6645331Samw if (ops->sa_rename_resource != NULL) 6655331Samw ret = ops->sa_rename_resource(handle, resource, 6665331Samw newname); 6675331Samw } 6685331Samw return (ret); 6695331Samw } 670