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 /* 2324424a35Sdougm * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 246185db85Sdougm * Use is subject to license terms. 256185db85Sdougm */ 266185db85Sdougm 276185db85Sdougm #pragma ident "%Z%%M% %I% %E% SMI" 286185db85Sdougm 296185db85Sdougm #include <stdio.h> 306185db85Sdougm #include <stdlib.h> 316185db85Sdougm #include <string.h> 326185db85Sdougm #include <libshare.h> 336185db85Sdougm #include "libshare_impl.h" 346185db85Sdougm #include <dlfcn.h> 356185db85Sdougm #include <link.h> 366185db85Sdougm #include <sys/types.h> 376185db85Sdougm #include <sys/param.h> 386185db85Sdougm #include <sys/stat.h> 396185db85Sdougm #include <dirent.h> 406185db85Sdougm #include <libintl.h> 41549ec3ffSdougm #include <sys/systeminfo.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 /* 596185db85Sdougm * proto_plugin_init() 606185db85Sdougm * 616185db85Sdougm * Initialize the protocol specific plugin modules. 626185db85Sdougm * 636185db85Sdougm * Walk /usr/lib/fs/\* for libshare_*.so modules. That is, 646185db85Sdougm * /usr/lib/fs/nfs/libshare_nfs.so. The protocol specific directory 656185db85Sdougm * would have a modules with name libshare_<proto>.so. If one is 666185db85Sdougm * found, initialize it and add to the internal list of 67*da6c28aaSamw * protocols. These are used for protocol specific operations. 686185db85Sdougm */ 696185db85Sdougm 706185db85Sdougm int 716185db85Sdougm proto_plugin_init() 726185db85Sdougm { 736185db85Sdougm struct sa_proto_plugin *proto; 746185db85Sdougm int num_protos = 0; 756185db85Sdougm int err; 766185db85Sdougm struct sa_plugin_ops *plugin_ops; 776185db85Sdougm void *dlhandle; 786185db85Sdougm DIR *dir; 796185db85Sdougm struct dirent *dent; 806185db85Sdougm int ret = SA_OK; 816185db85Sdougm struct stat st; 826185db85Sdougm 836185db85Sdougm /* 8425a68471Sdougm * Should walk "/usr/lib/fs/" for files of the form: 856185db85Sdougm * libshare_*.so 866185db85Sdougm */ 876185db85Sdougm dir = opendir(SA_LIB_DIR); 886185db85Sdougm if (dir != NULL) { 8925a68471Sdougm while (ret == SA_OK && (dent = readdir(dir)) != NULL) { 9025a68471Sdougm char path[MAXPATHLEN]; 9125a68471Sdougm char isa[MAXISALEN]; 92549ec3ffSdougm 93549ec3ffSdougm #if defined(_LP64) 9425a68471Sdougm if (sysinfo(SI_ARCHITECTURE_64, isa, MAXISALEN) == -1) 9525a68471Sdougm isa[0] = '\0'; 96549ec3ffSdougm #else 9725a68471Sdougm isa[0] = '\0'; 98549ec3ffSdougm #endif 9925a68471Sdougm (void) snprintf(path, MAXPATHLEN, 10025a68471Sdougm "%s/%s/%s/libshare_%s.so.1", SA_LIB_DIR, 10125a68471Sdougm dent->d_name, isa, dent->d_name); 10225a68471Sdougm /* 10325a68471Sdougm * If file doesn't exist, don't try to map it 10425a68471Sdougm */ 10525a68471Sdougm if (stat(path, &st) < 0) 10625a68471Sdougm continue; 10725a68471Sdougm 10825a68471Sdougm dlhandle = dlopen(path, RTLD_FIRST|RTLD_LAZY); 10925a68471Sdougm if (dlhandle != NULL) { 11025a68471Sdougm plugin_ops = (struct sa_plugin_ops *) 11125a68471Sdougm dlsym(dlhandle, "sa_plugin_ops"); 11225a68471Sdougm proto = (struct sa_proto_plugin *) 11325a68471Sdougm calloc(1, sizeof (struct sa_proto_plugin)); 11425a68471Sdougm if (proto != NULL) { 11525a68471Sdougm proto->plugin_ops = plugin_ops; 11625a68471Sdougm proto->plugin_handle = dlhandle; 11725a68471Sdougm num_protos++; 11825a68471Sdougm proto->plugin_next = sap_proto_list; 11925a68471Sdougm sap_proto_list = proto; 12025a68471Sdougm } else { 12125a68471Sdougm ret = SA_NO_MEMORY; 12225a68471Sdougm } 12325a68471Sdougm } else { 12425a68471Sdougm (void) fprintf(stderr, 12525a68471Sdougm dgettext(TEXT_DOMAIN, 12624424a35Sdougm "Error in plugin for protocol %s: %s\n"), 12725a68471Sdougm dent->d_name, dlerror()); 12825a68471Sdougm } 1296185db85Sdougm } 13025a68471Sdougm (void) closedir(dir); 1316185db85Sdougm } 1326185db85Sdougm if (ret == SA_OK) { 13325a68471Sdougm sa_proto_handle.sa_proto = 13425a68471Sdougm (char **)calloc(num_protos, sizeof (char *)); 13525a68471Sdougm sa_proto_handle.sa_ops = 13625a68471Sdougm (struct sa_plugin_ops **)calloc(num_protos, 13725a68471Sdougm sizeof (struct sa_plugin_ops *)); 13825a68471Sdougm if (sa_proto_handle.sa_proto != NULL && 13925a68471Sdougm sa_proto_handle.sa_ops != NULL) { 14025a68471Sdougm int i; 14125a68471Sdougm struct sa_proto_plugin *tmp; 14225a68471Sdougm 14325a68471Sdougm for (i = 0, tmp = sap_proto_list; 14425a68471Sdougm i < num_protos; 14525a68471Sdougm tmp = tmp->plugin_next) { 14625a68471Sdougm err = 0; 14725a68471Sdougm if (tmp->plugin_ops->sa_init != NULL) 14825a68471Sdougm err = tmp->plugin_ops->sa_init(); 14925a68471Sdougm if (err == SA_OK) { 15025a68471Sdougm /* 15125a68471Sdougm * Only include if the init 15225a68471Sdougm * succeeded or was NULL 15325a68471Sdougm */ 15425a68471Sdougm sa_proto_handle.sa_num_proto++; 15525a68471Sdougm sa_proto_handle.sa_ops[i] = 15625a68471Sdougm tmp->plugin_ops; 15725a68471Sdougm sa_proto_handle.sa_proto[i] = 15825a68471Sdougm tmp->plugin_ops->sa_protocol; 15925a68471Sdougm i++; 16025a68471Sdougm } 16125a68471Sdougm } 1626185db85Sdougm } 1636185db85Sdougm } else { 16425a68471Sdougm /* 16525a68471Sdougm * There was an error, so cleanup prior to return of failure. 16625a68471Sdougm */ 16725a68471Sdougm proto_plugin_fini(); 1686185db85Sdougm } 1696185db85Sdougm return (ret); 1706185db85Sdougm } 1716185db85Sdougm 1726185db85Sdougm /* 1736185db85Sdougm * proto_plugin_fini() 1746185db85Sdougm * 17525a68471Sdougm * Uninitialize all the plugin modules. 1766185db85Sdougm */ 1776185db85Sdougm 1786185db85Sdougm void 1796185db85Sdougm proto_plugin_fini() 1806185db85Sdougm { 1816185db85Sdougm /* 18225a68471Sdougm * Free up all the protocols, calling their fini, if there is 1836185db85Sdougm * one. 1846185db85Sdougm */ 1856185db85Sdougm while (sap_proto_list != NULL) { 18625a68471Sdougm struct sa_proto_plugin *next; 18725a68471Sdougm 18825a68471Sdougm next = sap_proto_list->plugin_next; 18925a68471Sdougm sap_proto_list->plugin_ops->sa_fini(); 19025a68471Sdougm if (sap_proto_list->plugin_handle != NULL) 19125a68471Sdougm (void) dlclose(sap_proto_list->plugin_handle); 19225a68471Sdougm free(sap_proto_list); 19325a68471Sdougm sap_proto_list = next; 1946185db85Sdougm } 1956185db85Sdougm if (sa_proto_handle.sa_ops != NULL) { 19625a68471Sdougm free(sa_proto_handle.sa_ops); 19725a68471Sdougm sa_proto_handle.sa_ops = NULL; 1986185db85Sdougm } 1996185db85Sdougm if (sa_proto_handle.sa_proto != NULL) { 20025a68471Sdougm free(sa_proto_handle.sa_proto); 20125a68471Sdougm sa_proto_handle.sa_proto = NULL; 2026185db85Sdougm } 2036185db85Sdougm sa_proto_handle.sa_num_proto = 0; 2046185db85Sdougm } 2056185db85Sdougm 2066185db85Sdougm /* 2076185db85Sdougm * find_protocol(proto) 2086185db85Sdougm * 2096185db85Sdougm * Search the plugin list for the specified protocol and return the 2106185db85Sdougm * ops vector. NULL if protocol is not defined. 2116185db85Sdougm */ 2126185db85Sdougm 2136185db85Sdougm static struct sa_plugin_ops * 2146185db85Sdougm find_protocol(char *proto) 2156185db85Sdougm { 2166185db85Sdougm int i; 2176185db85Sdougm 2186185db85Sdougm if (proto != NULL) { 21925a68471Sdougm for (i = 0; i < sa_proto_handle.sa_num_proto; i++) { 22025a68471Sdougm if (strcmp(proto, sa_proto_handle.sa_proto[i]) == 0) 22125a68471Sdougm return (sa_proto_handle.sa_ops[i]); 22225a68471Sdougm } 2236185db85Sdougm } 2246185db85Sdougm return (NULL); 2256185db85Sdougm } 2266185db85Sdougm 2276185db85Sdougm /* 2286185db85Sdougm * sa_proto_share(proto, share) 2296185db85Sdougm * 2306185db85Sdougm * Activate a share for the specified protocol. 2316185db85Sdougm */ 2326185db85Sdougm 2336185db85Sdougm int 2346185db85Sdougm sa_proto_share(char *proto, sa_share_t share) 2356185db85Sdougm { 2366185db85Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 2376185db85Sdougm int ret = SA_INVALID_PROTOCOL; 2386185db85Sdougm 2396185db85Sdougm if (ops != NULL && ops->sa_share != NULL) 24025a68471Sdougm ret = ops->sa_share(share); 2416185db85Sdougm return (ret); 2426185db85Sdougm } 2436185db85Sdougm 2446185db85Sdougm /* 245*da6c28aaSamw * sa_proto_unshare(proto, share) 2466185db85Sdougm * 247*da6c28aaSamw * Deactivate (unshare) the share for this protocol. 2486185db85Sdougm */ 2496185db85Sdougm 2506185db85Sdougm int 251ecd6cf80Smarks sa_proto_unshare(sa_share_t share, char *proto, char *path) 2526185db85Sdougm { 2536185db85Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 2546185db85Sdougm int ret = SA_INVALID_PROTOCOL; 2556185db85Sdougm 2566185db85Sdougm if (ops != NULL && ops->sa_unshare != NULL) 25725a68471Sdougm ret = ops->sa_unshare(share, path); 2586185db85Sdougm return (ret); 2596185db85Sdougm } 2606185db85Sdougm 261*da6c28aaSamw /* 262*da6c28aaSamw * sa_proto_share_resource(char *proto, sa_resource_t resource) 263*da6c28aaSamw * 264*da6c28aaSamw * For protocols that actually enable at the resource level, do the 265*da6c28aaSamw * protocol specific resource enable. If it doesn't, return an error. 266*da6c28aaSamw * Note that the resource functions are optional so can return 267*da6c28aaSamw * SA_NOT_SUPPORTED. 268*da6c28aaSamw */ 269*da6c28aaSamw 270*da6c28aaSamw int 271*da6c28aaSamw sa_proto_share_resource(char *proto, sa_resource_t resource) 272*da6c28aaSamw { 273*da6c28aaSamw struct sa_plugin_ops *ops = find_protocol(proto); 274*da6c28aaSamw int ret = SA_INVALID_PROTOCOL; 275*da6c28aaSamw 276*da6c28aaSamw if (ops != NULL) { 277*da6c28aaSamw if (ops->sa_enable_resource != NULL) 278*da6c28aaSamw ret = ops->sa_enable_resource(resource); 279*da6c28aaSamw else 280*da6c28aaSamw ret = SA_NOT_SUPPORTED; 281*da6c28aaSamw } 282*da6c28aaSamw return (ret); 283*da6c28aaSamw } 284*da6c28aaSamw 285*da6c28aaSamw /* 286*da6c28aaSamw * sa_proto_unshare_resource(char *proto, sa_resource_t resource) 287*da6c28aaSamw * 288*da6c28aaSamw * For protocols that actually disable at the resource level, do the 289*da6c28aaSamw * protocol specific resource disable. If it doesn't, return an error. 290*da6c28aaSamw */ 291*da6c28aaSamw 292*da6c28aaSamw int 293*da6c28aaSamw sa_proto_unshare_resource(char *proto, sa_resource_t resource) 294*da6c28aaSamw { 295*da6c28aaSamw struct sa_plugin_ops *ops = find_protocol(proto); 296*da6c28aaSamw int ret = SA_INVALID_PROTOCOL; 297*da6c28aaSamw 298*da6c28aaSamw if (ops != NULL) { 299*da6c28aaSamw if (ops->sa_disable_resource != NULL) 300*da6c28aaSamw ret = ops->sa_disable_resource(resource); 301*da6c28aaSamw else 302*da6c28aaSamw ret = SA_NOT_SUPPORTED; 303*da6c28aaSamw } 304*da6c28aaSamw return (ret); 305*da6c28aaSamw } 306*da6c28aaSamw 3076185db85Sdougm /* 3086185db85Sdougm * sa_proto_valid_prop(proto, prop, opt) 3096185db85Sdougm * 31025a68471Sdougm * Check to see if the specified prop is valid for this protocol. 3116185db85Sdougm */ 3126185db85Sdougm 3136185db85Sdougm int 3146185db85Sdougm sa_proto_valid_prop(char *proto, sa_property_t prop, sa_optionset_t opt) 3156185db85Sdougm { 3166185db85Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 3176185db85Sdougm int ret = 0; 3186185db85Sdougm 3196185db85Sdougm if (ops != NULL && ops->sa_valid_prop != NULL) 32025a68471Sdougm ret = ops->sa_valid_prop(prop, opt); 3216185db85Sdougm return (ret); 3226185db85Sdougm } 3236185db85Sdougm 3246185db85Sdougm /* 3256185db85Sdougm * sa_proto_valid_space(proto, space) 3266185db85Sdougm * 32725a68471Sdougm * Check if space is valid optionspace for proto. 3286185db85Sdougm * Protocols that don't implement this don't support spaces. 3296185db85Sdougm */ 3306185db85Sdougm int 3316185db85Sdougm sa_proto_valid_space(char *proto, char *token) 3326185db85Sdougm { 3336185db85Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 3346185db85Sdougm int ret = 0; 3356185db85Sdougm 3366185db85Sdougm if (ops != NULL && ops->sa_valid_space != NULL) 33725a68471Sdougm ret = ops->sa_valid_space(token); 3386185db85Sdougm return (ret); 3396185db85Sdougm } 3406185db85Sdougm 3416185db85Sdougm /* 3426185db85Sdougm * sa_proto_space_alias(proto, space) 3436185db85Sdougm * 34425a68471Sdougm * If the name for space is an alias, return its proper name. This is 3456185db85Sdougm * used to translate "default" values into proper form. 3466185db85Sdougm */ 3476185db85Sdougm char * 3486185db85Sdougm sa_proto_space_alias(char *proto, char *space) 3496185db85Sdougm { 3506185db85Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 3516185db85Sdougm char *ret = space; 3526185db85Sdougm 3536185db85Sdougm if (ops != NULL && ops->sa_space_alias != NULL) 35425a68471Sdougm ret = ops->sa_space_alias(space); 3556185db85Sdougm return (ret); 3566185db85Sdougm } 3576185db85Sdougm 3586185db85Sdougm /* 3596185db85Sdougm * sa_proto_security_prop(proto, token) 3606185db85Sdougm * 3616185db85Sdougm * Check to see if the property name in token is a valid named 3626185db85Sdougm * optionset property. 3636185db85Sdougm */ 3646185db85Sdougm 3656185db85Sdougm int 3666185db85Sdougm sa_proto_security_prop(char *proto, char *token) 3676185db85Sdougm { 3686185db85Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 3696185db85Sdougm int ret = 0; 3706185db85Sdougm 3716185db85Sdougm if (ops != NULL && ops->sa_security_prop != NULL) 37225a68471Sdougm ret = ops->sa_security_prop(token); 3736185db85Sdougm return (ret); 3746185db85Sdougm } 3756185db85Sdougm 3766185db85Sdougm /* 3776185db85Sdougm * sa_proto_legacy_opts(proto, grouup, options) 3786185db85Sdougm * 3796185db85Sdougm * Have the protocol specific parser parse the options string and add 3806185db85Sdougm * an appropriate optionset to group. 3816185db85Sdougm */ 3826185db85Sdougm 3836185db85Sdougm int 3846185db85Sdougm sa_proto_legacy_opts(char *proto, sa_group_t group, char *options) 3856185db85Sdougm { 3866185db85Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 3876185db85Sdougm int ret = SA_INVALID_PROTOCOL; 3886185db85Sdougm 3896185db85Sdougm if (ops != NULL && ops->sa_legacy_opts != NULL) 39025a68471Sdougm ret = ops->sa_legacy_opts(group, options); 3916185db85Sdougm return (ret); 3926185db85Sdougm } 3936185db85Sdougm 3946185db85Sdougm /* 3956185db85Sdougm * sa_proto_legacy_format(proto, group, hier) 3966185db85Sdougm * 3976185db85Sdougm * Return a legacy format string representing either the group's 3986185db85Sdougm * properties or the groups hierarchical properties. 3996185db85Sdougm */ 4006185db85Sdougm 4016185db85Sdougm char * 4026185db85Sdougm sa_proto_legacy_format(char *proto, sa_group_t group, int hier) 4036185db85Sdougm { 4046185db85Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 4056185db85Sdougm char *ret = NULL; 4066185db85Sdougm 4076185db85Sdougm if (ops != NULL && ops->sa_legacy_format != NULL) 40825a68471Sdougm ret = ops->sa_legacy_format(group, hier); 4096185db85Sdougm return (ret); 4106185db85Sdougm } 4116185db85Sdougm 4126185db85Sdougm void 4136185db85Sdougm sa_format_free(char *str) 4146185db85Sdougm { 4156185db85Sdougm free(str); 4166185db85Sdougm } 4176185db85Sdougm 4186185db85Sdougm /* 4196185db85Sdougm * sharectl related API functions 4206185db85Sdougm */ 4216185db85Sdougm 4226185db85Sdougm /* 4236185db85Sdougm * sa_proto_get_properties(proto) 4246185db85Sdougm * 4256185db85Sdougm * Return the set of properties that are specific to the 4266185db85Sdougm * protocol. These are usually in /etc/dfs/<proto> and related files, 4276185db85Sdougm * but only the protocol module knows which ones for sure. 4286185db85Sdougm */ 4296185db85Sdougm 4306185db85Sdougm sa_protocol_properties_t 4316185db85Sdougm sa_proto_get_properties(char *proto) 4326185db85Sdougm { 4336185db85Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 4346185db85Sdougm sa_protocol_properties_t props = NULL; 4356185db85Sdougm 4366185db85Sdougm if (ops != NULL && ops->sa_get_proto_set != NULL) 43725a68471Sdougm props = ops->sa_get_proto_set(); 4386185db85Sdougm return (props); 4396185db85Sdougm } 4406185db85Sdougm 4416185db85Sdougm /* 4426185db85Sdougm * sa_proto_set_property(proto, prop) 4436185db85Sdougm * 444*da6c28aaSamw * Update the protocol specific property. 4456185db85Sdougm */ 4466185db85Sdougm 4476185db85Sdougm int 4486185db85Sdougm sa_proto_set_property(char *proto, sa_property_t prop) 4496185db85Sdougm { 4506185db85Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 4516185db85Sdougm int ret = SA_OK; 45225a68471Sdougm 4536185db85Sdougm if (ops != NULL && ops->sa_set_proto_prop != NULL) 45425a68471Sdougm ret = ops->sa_set_proto_prop(prop); 4556185db85Sdougm return (ret); 4566185db85Sdougm } 4576185db85Sdougm 4586185db85Sdougm /* 4596185db85Sdougm * sa_valid_protocol(proto) 4606185db85Sdougm * 46125a68471Sdougm * Check to see if the protocol specified is defined by a 4626185db85Sdougm * plugin. Returns true (1) or false (0) 4636185db85Sdougm */ 4646185db85Sdougm 4656185db85Sdougm int 4666185db85Sdougm sa_valid_protocol(char *proto) 4676185db85Sdougm { 4686185db85Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 4696185db85Sdougm return (ops != NULL); 4706185db85Sdougm } 4716185db85Sdougm 4726185db85Sdougm /* 4736185db85Sdougm * Return the current operational status of the protocol 4746185db85Sdougm */ 4756185db85Sdougm 4766185db85Sdougm char * 4776185db85Sdougm sa_get_protocol_status(char *proto) 4786185db85Sdougm { 4796185db85Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 4806185db85Sdougm char *ret = NULL; 4816185db85Sdougm if (ops != NULL && ops->sa_get_proto_status != NULL) 48225a68471Sdougm ret = ops->sa_get_proto_status(proto); 4836185db85Sdougm return (ret); 4846185db85Sdougm } 4856185db85Sdougm 4866185db85Sdougm /* 4876185db85Sdougm * sa_proto_update_legacy(proto, share) 4886185db85Sdougm * 4896185db85Sdougm * Update the protocol specific legacy files if necessary for the 4906185db85Sdougm * specified share. 4916185db85Sdougm */ 4926185db85Sdougm 4936185db85Sdougm int 4946185db85Sdougm sa_proto_update_legacy(char *proto, sa_share_t share) 4956185db85Sdougm { 4966185db85Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 4976185db85Sdougm int ret = SA_NOT_IMPLEMENTED; 4986185db85Sdougm 4996185db85Sdougm if (ops != NULL) { 50025a68471Sdougm if (ops->sa_update_legacy != NULL) 50125a68471Sdougm ret = ops->sa_update_legacy(share); 5026185db85Sdougm } 5036185db85Sdougm return (ret); 5046185db85Sdougm } 5056185db85Sdougm 5066185db85Sdougm /* 5076185db85Sdougm * sa_delete_legacy(proto, share) 5086185db85Sdougm * 50925a68471Sdougm * Remove the specified share from the protocol specific legacy files. 5106185db85Sdougm */ 5116185db85Sdougm 5126185db85Sdougm int 5136185db85Sdougm sa_proto_delete_legacy(char *proto, sa_share_t share) 5146185db85Sdougm { 5156185db85Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 516*da6c28aaSamw int ret = SA_NOT_IMPLEMENTED; 5176185db85Sdougm 5186185db85Sdougm if (ops != NULL) { 51925a68471Sdougm if (ops->sa_delete_legacy != NULL) 52025a68471Sdougm ret = ops->sa_delete_legacy(share); 521*da6c28aaSamw } else if (proto == NULL) { 522*da6c28aaSamw ret = SA_INVALID_PROTOCOL; 523*da6c28aaSamw } 524*da6c28aaSamw return (ret); 525*da6c28aaSamw } 526*da6c28aaSamw 527*da6c28aaSamw /* 528*da6c28aaSamw * sa_proto_change_notify(share, char *protocol) 529*da6c28aaSamw * 530*da6c28aaSamw * Notify the protocol that a change has been made to the share 531*da6c28aaSamw */ 532*da6c28aaSamw 533*da6c28aaSamw int 534*da6c28aaSamw sa_proto_change_notify(sa_share_t share, char *proto) 535*da6c28aaSamw { 536*da6c28aaSamw struct sa_plugin_ops *ops = find_protocol(proto); 537*da6c28aaSamw int ret = SA_NOT_IMPLEMENTED; 538*da6c28aaSamw 539*da6c28aaSamw if (ops != NULL) { 540*da6c28aaSamw if (ops->sa_change_notify != NULL) 541*da6c28aaSamw ret = ops->sa_change_notify(share); 542*da6c28aaSamw } else if (proto == NULL) { 54325a68471Sdougm ret = SA_INVALID_PROTOCOL; 5446185db85Sdougm } 5456185db85Sdougm return (ret); 5466185db85Sdougm } 547*da6c28aaSamw 548*da6c28aaSamw /* 549*da6c28aaSamw * sa_proto_notify_resource(resource, char *protocol) 550*da6c28aaSamw * 551*da6c28aaSamw * Notify the protocol that a change has been made to the share 552*da6c28aaSamw */ 553*da6c28aaSamw 554*da6c28aaSamw int 555*da6c28aaSamw sa_proto_notify_resource(sa_resource_t resource, char *proto) 556*da6c28aaSamw { 557*da6c28aaSamw struct sa_plugin_ops *ops = find_protocol(proto); 558*da6c28aaSamw int ret = SA_NOT_IMPLEMENTED; 559*da6c28aaSamw 560*da6c28aaSamw if (ops != NULL) { 561*da6c28aaSamw if (ops->sa_notify_resource != NULL) 562*da6c28aaSamw ret = ops->sa_notify_resource(resource); 563*da6c28aaSamw } else if (proto == NULL) { 564*da6c28aaSamw ret = SA_INVALID_PROTOCOL; 565*da6c28aaSamw } 566*da6c28aaSamw return (ret); 567*da6c28aaSamw } 568*da6c28aaSamw 569*da6c28aaSamw /* 570*da6c28aaSamw * sa_proto_get_featureset(protocol) 571*da6c28aaSamw * 572*da6c28aaSamw * Get bitmask of defined features of the protocol. These are 573*da6c28aaSamw * primarily things like SA_FEATURE_RESOURCE (shares are by resource 574*da6c28aaSamw * name rather than path) and other operational features that affect 575*da6c28aaSamw * behavior. 576*da6c28aaSamw */ 577*da6c28aaSamw 578*da6c28aaSamw uint64_t 579*da6c28aaSamw sa_proto_get_featureset(char *proto) 580*da6c28aaSamw { 581*da6c28aaSamw struct sa_plugin_ops *ops = find_protocol(proto); 582*da6c28aaSamw uint64_t ret = 0; 583*da6c28aaSamw 584*da6c28aaSamw if (ops != NULL) { 585*da6c28aaSamw if (ops->sa_features != NULL) 586*da6c28aaSamw ret = ops->sa_features(); 587*da6c28aaSamw } 588*da6c28aaSamw /* if not implemented, zero is valid */ 589*da6c28aaSamw return (ret); 590*da6c28aaSamw } 591*da6c28aaSamw 592*da6c28aaSamw /* 593*da6c28aaSamw * sa_proto_get_transients(sa_handle_t) 594*da6c28aaSamw * 595*da6c28aaSamw * Called to get any protocol specific transient shares. NFS doesn't 596*da6c28aaSamw * use this since the info is in sharetab which is processed as a 597*da6c28aaSamw * common transient store. 598*da6c28aaSamw * 599*da6c28aaSamw * The protocol plugin should verify that the share isn't in the 600*da6c28aaSamw * repository and then add it as a transient. 601*da6c28aaSamw * 602*da6c28aaSamw * Not having an entry is not a problem. It returns 0 in that case. 603*da6c28aaSamw */ 604*da6c28aaSamw 605*da6c28aaSamw int 606*da6c28aaSamw sa_proto_get_transients(sa_handle_t handle, char *proto) 607*da6c28aaSamw { 608*da6c28aaSamw struct sa_plugin_ops *ops = find_protocol(proto); 609*da6c28aaSamw int ret = 0; 610*da6c28aaSamw 611*da6c28aaSamw if (ops != NULL) { 612*da6c28aaSamw if (ops->sa_get_transient_shares != NULL) 613*da6c28aaSamw ret = ops->sa_get_transient_shares(handle); 614*da6c28aaSamw } 615*da6c28aaSamw return (ret); 616*da6c28aaSamw } 617*da6c28aaSamw 618*da6c28aaSamw /* 619*da6c28aaSamw * sa_proto_rename_resource(sa_handle_t, proto, sa_resource_t, newname) 620*da6c28aaSamw * 621*da6c28aaSamw * Protocols may need to know when a resource has changed names in 622*da6c28aaSamw * order to notify clients. This must be done "before" the name in the 623*da6c28aaSamw * resource has been changed. Not being implemented is not a problem. 624*da6c28aaSamw */ 625*da6c28aaSamw 626*da6c28aaSamw int 627*da6c28aaSamw sa_proto_rename_resource(sa_handle_t handle, char *proto, 628*da6c28aaSamw sa_resource_t resource, char *newname) 629*da6c28aaSamw { 630*da6c28aaSamw struct sa_plugin_ops *ops = find_protocol(proto); 631*da6c28aaSamw int ret = SA_OK; 632*da6c28aaSamw 633*da6c28aaSamw if (ops != NULL) { 634*da6c28aaSamw if (ops->sa_rename_resource != NULL) 635*da6c28aaSamw ret = ops->sa_rename_resource(handle, resource, 636*da6c28aaSamw newname); 637*da6c28aaSamw } 638*da6c28aaSamw return (ret); 639*da6c28aaSamw } 640