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 /* 23*6007Sthurlow * 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; 1444653Sdougm i < num_protos; 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 /* 3083034Sdougm * sa_proto_valid_prop(proto, prop, opt) 3093034Sdougm * 3104653Sdougm * Check to see if the specified prop is valid for this protocol. 3113034Sdougm */ 3123034Sdougm 3133034Sdougm int 3143034Sdougm sa_proto_valid_prop(char *proto, sa_property_t prop, sa_optionset_t opt) 3153034Sdougm { 3163034Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 3173034Sdougm int ret = 0; 3183034Sdougm 3193034Sdougm if (ops != NULL && ops->sa_valid_prop != NULL) 3204653Sdougm ret = ops->sa_valid_prop(prop, opt); 3213034Sdougm return (ret); 3223034Sdougm } 3233034Sdougm 3243034Sdougm /* 3253034Sdougm * sa_proto_valid_space(proto, space) 3263034Sdougm * 3274653Sdougm * Check if space is valid optionspace for proto. 3283034Sdougm * Protocols that don't implement this don't support spaces. 3293034Sdougm */ 3303034Sdougm int 3313034Sdougm sa_proto_valid_space(char *proto, char *token) 3323034Sdougm { 3333034Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 3343034Sdougm int ret = 0; 3353034Sdougm 3363034Sdougm if (ops != NULL && ops->sa_valid_space != NULL) 3374653Sdougm ret = ops->sa_valid_space(token); 3383034Sdougm return (ret); 3393034Sdougm } 3403034Sdougm 3413034Sdougm /* 3423034Sdougm * sa_proto_space_alias(proto, space) 3433034Sdougm * 3444653Sdougm * If the name for space is an alias, return its proper name. This is 3453034Sdougm * used to translate "default" values into proper form. 3463034Sdougm */ 3473034Sdougm char * 3483034Sdougm sa_proto_space_alias(char *proto, char *space) 3493034Sdougm { 3503034Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 3513034Sdougm char *ret = space; 3523034Sdougm 3533034Sdougm if (ops != NULL && ops->sa_space_alias != NULL) 3544653Sdougm ret = ops->sa_space_alias(space); 3553034Sdougm return (ret); 3563034Sdougm } 3573034Sdougm 3583034Sdougm /* 3593034Sdougm * sa_proto_security_prop(proto, token) 3603034Sdougm * 3613034Sdougm * Check to see if the property name in token is a valid named 3623034Sdougm * optionset property. 3633034Sdougm */ 3643034Sdougm 3653034Sdougm int 3663034Sdougm sa_proto_security_prop(char *proto, char *token) 3673034Sdougm { 3683034Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 3693034Sdougm int ret = 0; 3703034Sdougm 3713034Sdougm if (ops != NULL && ops->sa_security_prop != NULL) 3724653Sdougm ret = ops->sa_security_prop(token); 3733034Sdougm return (ret); 3743034Sdougm } 3753034Sdougm 3763034Sdougm /* 3773034Sdougm * sa_proto_legacy_opts(proto, grouup, options) 3783034Sdougm * 3793034Sdougm * Have the protocol specific parser parse the options string and add 3803034Sdougm * an appropriate optionset to group. 3813034Sdougm */ 3823034Sdougm 3833034Sdougm int 3843034Sdougm sa_proto_legacy_opts(char *proto, sa_group_t group, char *options) 3853034Sdougm { 3863034Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 3873034Sdougm int ret = SA_INVALID_PROTOCOL; 3883034Sdougm 3893034Sdougm if (ops != NULL && ops->sa_legacy_opts != NULL) 3904653Sdougm ret = ops->sa_legacy_opts(group, options); 3913034Sdougm return (ret); 3923034Sdougm } 3933034Sdougm 3943034Sdougm /* 3953034Sdougm * sa_proto_legacy_format(proto, group, hier) 3963034Sdougm * 3973034Sdougm * Return a legacy format string representing either the group's 3983034Sdougm * properties or the groups hierarchical properties. 3993034Sdougm */ 4003034Sdougm 4013034Sdougm char * 4023034Sdougm sa_proto_legacy_format(char *proto, sa_group_t group, int hier) 4033034Sdougm { 4043034Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 4053034Sdougm char *ret = NULL; 4063034Sdougm 4073034Sdougm if (ops != NULL && ops->sa_legacy_format != NULL) 4084653Sdougm ret = ops->sa_legacy_format(group, hier); 4093034Sdougm return (ret); 4103034Sdougm } 4113034Sdougm 4123034Sdougm void 4133034Sdougm sa_format_free(char *str) 4143034Sdougm { 4153034Sdougm free(str); 4163034Sdougm } 4173034Sdougm 4183034Sdougm /* 4193034Sdougm * sharectl related API functions 4203034Sdougm */ 4213034Sdougm 4223034Sdougm /* 4233034Sdougm * sa_proto_get_properties(proto) 4243034Sdougm * 4253034Sdougm * Return the set of properties that are specific to the 4263034Sdougm * protocol. These are usually in /etc/dfs/<proto> and related files, 4273034Sdougm * but only the protocol module knows which ones for sure. 4283034Sdougm */ 4293034Sdougm 4303034Sdougm sa_protocol_properties_t 4313034Sdougm sa_proto_get_properties(char *proto) 4323034Sdougm { 4333034Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 4343034Sdougm sa_protocol_properties_t props = NULL; 4353034Sdougm 4363034Sdougm if (ops != NULL && ops->sa_get_proto_set != NULL) 4374653Sdougm props = ops->sa_get_proto_set(); 4383034Sdougm return (props); 4393034Sdougm } 4403034Sdougm 4413034Sdougm /* 4423034Sdougm * sa_proto_set_property(proto, prop) 4433034Sdougm * 4445331Samw * Update the protocol specific property. 4453034Sdougm */ 4463034Sdougm 4473034Sdougm int 4483034Sdougm sa_proto_set_property(char *proto, sa_property_t prop) 4493034Sdougm { 4503034Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 4513034Sdougm int ret = SA_OK; 4524653Sdougm 4533034Sdougm if (ops != NULL && ops->sa_set_proto_prop != NULL) 4544653Sdougm ret = ops->sa_set_proto_prop(prop); 4553034Sdougm return (ret); 4563034Sdougm } 4573034Sdougm 4583034Sdougm /* 4593034Sdougm * sa_valid_protocol(proto) 4603034Sdougm * 4614653Sdougm * Check to see if the protocol specified is defined by a 4623034Sdougm * plugin. Returns true (1) or false (0) 4633034Sdougm */ 4643034Sdougm 4653034Sdougm int 4663034Sdougm sa_valid_protocol(char *proto) 4673034Sdougm { 4683034Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 4693034Sdougm return (ops != NULL); 4703034Sdougm } 4713034Sdougm 4723034Sdougm /* 4733034Sdougm * Return the current operational status of the protocol 4743034Sdougm */ 4753034Sdougm 4763034Sdougm char * 4773034Sdougm sa_get_protocol_status(char *proto) 4783034Sdougm { 4793034Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 4803034Sdougm char *ret = NULL; 4813034Sdougm if (ops != NULL && ops->sa_get_proto_status != NULL) 4824653Sdougm ret = ops->sa_get_proto_status(proto); 4833034Sdougm return (ret); 4843034Sdougm } 4853034Sdougm 4863034Sdougm /* 4873034Sdougm * sa_proto_update_legacy(proto, share) 4883034Sdougm * 4893034Sdougm * Update the protocol specific legacy files if necessary for the 4903034Sdougm * specified share. 4913034Sdougm */ 4923034Sdougm 4933034Sdougm int 4943034Sdougm sa_proto_update_legacy(char *proto, sa_share_t share) 4953034Sdougm { 4963034Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 4973034Sdougm int ret = SA_NOT_IMPLEMENTED; 4983034Sdougm 4993034Sdougm if (ops != NULL) { 5004653Sdougm if (ops->sa_update_legacy != NULL) 5014653Sdougm ret = ops->sa_update_legacy(share); 5023034Sdougm } 5033034Sdougm return (ret); 5043034Sdougm } 5053034Sdougm 5063034Sdougm /* 5073034Sdougm * sa_delete_legacy(proto, share) 5083034Sdougm * 5094653Sdougm * Remove the specified share from the protocol specific legacy files. 5103034Sdougm */ 5113034Sdougm 5123034Sdougm int 5133034Sdougm sa_proto_delete_legacy(char *proto, sa_share_t share) 5143034Sdougm { 5153034Sdougm struct sa_plugin_ops *ops = find_protocol(proto); 5165331Samw int ret = SA_NOT_IMPLEMENTED; 5173034Sdougm 5183034Sdougm if (ops != NULL) { 5194653Sdougm if (ops->sa_delete_legacy != NULL) 5204653Sdougm ret = ops->sa_delete_legacy(share); 521*6007Sthurlow } else { 522*6007Sthurlow if (proto != NULL) 523*6007Sthurlow ret = SA_NOT_IMPLEMENTED; 524*6007Sthurlow else 525*6007Sthurlow ret = SA_INVALID_PROTOCOL; 526*6007Sthurlow } 527*6007Sthurlow return (ret); 528*6007Sthurlow } 529*6007Sthurlow 530*6007Sthurlow /* 531*6007Sthurlow * sa_proto_delete_section(proto, section) 532*6007Sthurlow * 533*6007Sthurlow * Remove the specified section from the protocol specific legacy files, 534*6007Sthurlow * if supported. 535*6007Sthurlow */ 536*6007Sthurlow 537*6007Sthurlow int 538*6007Sthurlow sa_proto_delete_section(char *proto, char *section) 539*6007Sthurlow { 540*6007Sthurlow struct sa_plugin_ops *ops = find_protocol(proto); 541*6007Sthurlow int ret = SA_OK; 542*6007Sthurlow 543*6007Sthurlow if (ops != NULL) { 544*6007Sthurlow if (ops->sa_delete_proto_section != NULL) 545*6007Sthurlow ret = ops->sa_delete_proto_section(section); 546*6007Sthurlow } else { 547*6007Sthurlow if (proto != NULL) 548*6007Sthurlow ret = SA_NOT_IMPLEMENTED; 549*6007Sthurlow else 550*6007Sthurlow ret = SA_INVALID_PROTOCOL; 5515331Samw } 5525331Samw return (ret); 5535331Samw } 5545331Samw 5555331Samw /* 5565331Samw * sa_proto_change_notify(share, char *protocol) 5575331Samw * 5585331Samw * Notify the protocol that a change has been made to the share 5595331Samw */ 5605331Samw 5615331Samw int 5625331Samw sa_proto_change_notify(sa_share_t share, char *proto) 5635331Samw { 5645331Samw struct sa_plugin_ops *ops = find_protocol(proto); 5655331Samw int ret = SA_NOT_IMPLEMENTED; 5665331Samw 5675331Samw if (ops != NULL) { 5685331Samw if (ops->sa_change_notify != NULL) 5695331Samw ret = ops->sa_change_notify(share); 5705331Samw } else if (proto == NULL) { 571*6007Sthurlow 5725331Samw ret = SA_INVALID_PROTOCOL; 5735331Samw } 5745331Samw return (ret); 5755331Samw } 5765331Samw 5775331Samw /* 5785331Samw * sa_proto_notify_resource(resource, char *protocol) 5795331Samw * 5805331Samw * Notify the protocol that a change has been made to the share 5815331Samw */ 5825331Samw 5835331Samw int 5845331Samw sa_proto_notify_resource(sa_resource_t resource, char *proto) 5855331Samw { 5865331Samw struct sa_plugin_ops *ops = find_protocol(proto); 5875331Samw int ret = SA_NOT_IMPLEMENTED; 5885331Samw 5895331Samw if (ops != NULL) { 5905331Samw if (ops->sa_notify_resource != NULL) 5915331Samw ret = ops->sa_notify_resource(resource); 5925331Samw } else if (proto == NULL) { 5934653Sdougm ret = SA_INVALID_PROTOCOL; 5943034Sdougm } 5953034Sdougm return (ret); 5963034Sdougm } 5975331Samw 5985331Samw /* 5995331Samw * sa_proto_get_featureset(protocol) 6005331Samw * 6015331Samw * Get bitmask of defined features of the protocol. These are 6025331Samw * primarily things like SA_FEATURE_RESOURCE (shares are by resource 6035331Samw * name rather than path) and other operational features that affect 6045331Samw * behavior. 6055331Samw */ 6065331Samw 6075331Samw uint64_t 6085331Samw sa_proto_get_featureset(char *proto) 6095331Samw { 6105331Samw struct sa_plugin_ops *ops = find_protocol(proto); 6115331Samw uint64_t ret = 0; 6125331Samw 6135331Samw if (ops != NULL) { 6145331Samw if (ops->sa_features != NULL) 6155331Samw ret = ops->sa_features(); 6165331Samw } 6175331Samw /* if not implemented, zero is valid */ 6185331Samw return (ret); 6195331Samw } 6205331Samw 6215331Samw /* 6225331Samw * sa_proto_get_transients(sa_handle_t) 6235331Samw * 6245331Samw * Called to get any protocol specific transient shares. NFS doesn't 6255331Samw * use this since the info is in sharetab which is processed as a 6265331Samw * common transient store. 6275331Samw * 6285331Samw * The protocol plugin should verify that the share isn't in the 6295331Samw * repository and then add it as a transient. 6305331Samw * 6315331Samw * Not having an entry is not a problem. It returns 0 in that case. 6325331Samw */ 6335331Samw 6345331Samw int 6355331Samw sa_proto_get_transients(sa_handle_t handle, char *proto) 6365331Samw { 6375331Samw struct sa_plugin_ops *ops = find_protocol(proto); 6385331Samw int ret = 0; 6395331Samw 6405331Samw if (ops != NULL) { 6415331Samw if (ops->sa_get_transient_shares != NULL) 6425331Samw ret = ops->sa_get_transient_shares(handle); 6435331Samw } 6445331Samw return (ret); 6455331Samw } 6465331Samw 6475331Samw /* 6485331Samw * sa_proto_rename_resource(sa_handle_t, proto, sa_resource_t, newname) 6495331Samw * 6505331Samw * Protocols may need to know when a resource has changed names in 6515331Samw * order to notify clients. This must be done "before" the name in the 6525331Samw * resource has been changed. Not being implemented is not a problem. 6535331Samw */ 6545331Samw 6555331Samw int 6565331Samw sa_proto_rename_resource(sa_handle_t handle, char *proto, 6575331Samw sa_resource_t resource, char *newname) 6585331Samw { 6595331Samw struct sa_plugin_ops *ops = find_protocol(proto); 6605331Samw int ret = SA_OK; 6615331Samw 6625331Samw if (ops != NULL) { 6635331Samw if (ops->sa_rename_resource != NULL) 6645331Samw ret = ops->sa_rename_resource(handle, resource, 6655331Samw newname); 6665331Samw } 6675331Samw return (ret); 6685331Samw } 669