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