summaryrefslogtreecommitdiff
path: root/usr/src/lib/libshare/common/plugin.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libshare/common/plugin.c')
-rw-r--r--usr/src/lib/libshare/common/plugin.c25
1 files changed, 14 insertions, 11 deletions
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);