diff options
Diffstat (limited to 'usr/src/lib/libshare/common')
-rw-r--r-- | usr/src/lib/libshare/common/libshare.c | 11 | ||||
-rw-r--r-- | usr/src/lib/libshare/common/plugin.c | 25 |
2 files changed, 20 insertions, 16 deletions
diff --git a/usr/src/lib/libshare/common/libshare.c b/usr/src/lib/libshare/common/libshare.c index 8fbf1e82ae..cbe5aae3bb 100644 --- a/usr/src/lib/libshare/common/libshare.c +++ b/usr/src/lib/libshare/common/libshare.c @@ -1025,15 +1025,10 @@ sa_fini(sa_handle_t handle) */ if (impl_handle->doc != NULL) xmlFreeDoc(impl_handle->doc); - sa_scf_fini(impl_handle->scfhandle); - sa_zfs_fini(impl_handle); /* Remove and free the entry in the global list. */ remove_handle_for_root(impl_handle->tree); - /* Make sure we free the handle */ - free(impl_handle); - /* * If this was the last handle to release, unload the * plugins that were loaded. Use a mutex in case @@ -1044,6 +1039,12 @@ sa_fini(sa_handle_t handle) (void) proto_plugin_fini(); (void) mutex_unlock(&sa_global_lock); + sa_scf_fini(impl_handle->scfhandle); + sa_zfs_fini(impl_handle); + + /* Make sure we free the handle */ + free(impl_handle); + } } diff --git a/usr/src/lib/libshare/common/plugin.c b/usr/src/lib/libshare/common/plugin.c index 2721715ef2..032793cd79 100644 --- a/usr/src/lib/libshare/common/plugin.c +++ b/usr/src/lib/libshare/common/plugin.c @@ -187,19 +187,22 @@ proto_plugin_init() void proto_plugin_fini() { + struct sa_proto_plugin *p; + /* - * Free up all the protocols, calling their fini, if there is - * one. + * Protocols may call this framework during _fini + * (the smbfs plugin is known to do this) so do + * two passes: 1st call _fini; 2nd free, dlclose. */ - while (sap_proto_list != NULL) { - struct sa_proto_plugin *next; - - next = sap_proto_list->plugin_next; - sap_proto_list->plugin_ops->sa_fini(); - if (sap_proto_list->plugin_handle != NULL) - (void) dlclose(sap_proto_list->plugin_handle); - free(sap_proto_list); - sap_proto_list = next; + for (p = sap_proto_list; p != NULL; p = p->plugin_next) + p->plugin_ops->sa_fini(); + + while ((p = sap_proto_list) != NULL) { + sap_proto_list = p->plugin_next; + + if (p->plugin_handle != NULL) + (void) dlclose(p->plugin_handle); + free(p); } if (sa_proto_handle.sa_ops != NULL) { free(sa_proto_handle.sa_ops); |