17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate /* 237c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate #include <dlfcn.h> 307c478bd9Sstevel@tonic-gate #include <link.h> 317c478bd9Sstevel@tonic-gate 327c478bd9Sstevel@tonic-gate #include <fmd_module.h> 337c478bd9Sstevel@tonic-gate #include <fmd_error.h> 347c478bd9Sstevel@tonic-gate #include <fmd_alloc.h> 357c478bd9Sstevel@tonic-gate #include <fmd_subr.h> 367c478bd9Sstevel@tonic-gate #include <fmd_event.h> 377c478bd9Sstevel@tonic-gate #include <fmd.h> 387c478bd9Sstevel@tonic-gate 397c478bd9Sstevel@tonic-gate typedef struct fmd_rtld { 407c478bd9Sstevel@tonic-gate void *rtld_dlp; /* libdl(3DL) handle for shared library */ 417c478bd9Sstevel@tonic-gate void (*rtld_init)(fmd_hdl_t *); /* shared library's _fmd_init() */ 427c478bd9Sstevel@tonic-gate void (*rtld_fini)(fmd_hdl_t *); /* shared library's _fmd_fini() */ 437c478bd9Sstevel@tonic-gate } fmd_rtld_t; 447c478bd9Sstevel@tonic-gate 457c478bd9Sstevel@tonic-gate static int 467c478bd9Sstevel@tonic-gate rtld_init(fmd_module_t *mp) 477c478bd9Sstevel@tonic-gate { 487c478bd9Sstevel@tonic-gate fmd_rtld_t *rp; 497c478bd9Sstevel@tonic-gate void *dlp; 507c478bd9Sstevel@tonic-gate 517c478bd9Sstevel@tonic-gate if ((dlp = dlopen(mp->mod_path, RTLD_LOCAL | RTLD_NOW)) == NULL) { 527c478bd9Sstevel@tonic-gate fmd_error(EFMD_RTLD_OPEN, "%s\n", dlerror()); 537c478bd9Sstevel@tonic-gate return (fmd_set_errno(EFMD_RTLD_OPEN)); 547c478bd9Sstevel@tonic-gate } 557c478bd9Sstevel@tonic-gate 567c478bd9Sstevel@tonic-gate rp = mp->mod_data = fmd_alloc(sizeof (fmd_rtld_t), FMD_SLEEP); 577c478bd9Sstevel@tonic-gate 587c478bd9Sstevel@tonic-gate rp->rtld_dlp = dlp; 597c478bd9Sstevel@tonic-gate rp->rtld_init = (void (*)())dlsym(dlp, "_fmd_init"); 607c478bd9Sstevel@tonic-gate rp->rtld_fini = (void (*)())dlsym(dlp, "_fmd_fini"); 617c478bd9Sstevel@tonic-gate 627c478bd9Sstevel@tonic-gate if (rp->rtld_init == NULL) { 637c478bd9Sstevel@tonic-gate (void) dlclose(dlp); 647c478bd9Sstevel@tonic-gate fmd_free(rp, sizeof (fmd_rtld_t)); 657c478bd9Sstevel@tonic-gate return (fmd_set_errno(EFMD_RTLD_INIT)); 667c478bd9Sstevel@tonic-gate } 677c478bd9Sstevel@tonic-gate 687c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&mp->mod_lock); 697c478bd9Sstevel@tonic-gate 707c478bd9Sstevel@tonic-gate /* 717c478bd9Sstevel@tonic-gate * Call _fmd_init() in the module. If this causes a module abort and 727c478bd9Sstevel@tonic-gate * mod_info has been registered, unregister it on behalf of the module. 737c478bd9Sstevel@tonic-gate */ 747c478bd9Sstevel@tonic-gate if (fmd_module_enter(mp, rp->rtld_init) != 0 && mp->mod_info != NULL) 757c478bd9Sstevel@tonic-gate fmd_hdl_unregister((fmd_hdl_t *)mp); 767c478bd9Sstevel@tonic-gate 777c478bd9Sstevel@tonic-gate fmd_module_exit(mp); 787c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&mp->mod_lock); 797c478bd9Sstevel@tonic-gate 807c478bd9Sstevel@tonic-gate if (mp->mod_info == NULL) { 817c478bd9Sstevel@tonic-gate (void) dlclose(dlp); 827c478bd9Sstevel@tonic-gate fmd_free(rp, sizeof (fmd_rtld_t)); 837c478bd9Sstevel@tonic-gate return (fmd_set_errno(EFMD_HDL_INIT)); 847c478bd9Sstevel@tonic-gate } 857c478bd9Sstevel@tonic-gate 867c478bd9Sstevel@tonic-gate return (0); 877c478bd9Sstevel@tonic-gate } 887c478bd9Sstevel@tonic-gate 897c478bd9Sstevel@tonic-gate static int 907c478bd9Sstevel@tonic-gate rtld_fini(fmd_module_t *mp) 917c478bd9Sstevel@tonic-gate { 927c478bd9Sstevel@tonic-gate fmd_rtld_t *rp = mp->mod_data; 937c478bd9Sstevel@tonic-gate int doclose = 1, err = 0; 947c478bd9Sstevel@tonic-gate 957c478bd9Sstevel@tonic-gate if (mp->mod_info != NULL) { 967c478bd9Sstevel@tonic-gate (void) fmd_module_enter(mp, rp->rtld_fini); 977c478bd9Sstevel@tonic-gate 987c478bd9Sstevel@tonic-gate if (mp->mod_info != NULL) { 997c478bd9Sstevel@tonic-gate fmd_module_lock(mp); 1007c478bd9Sstevel@tonic-gate fmd_module_unregister(mp); 1017c478bd9Sstevel@tonic-gate fmd_module_unlock(mp); 1027c478bd9Sstevel@tonic-gate } 1037c478bd9Sstevel@tonic-gate 1047c478bd9Sstevel@tonic-gate fmd_module_exit(mp); 1057c478bd9Sstevel@tonic-gate } 1067c478bd9Sstevel@tonic-gate 1077c478bd9Sstevel@tonic-gate (void) fmd_conf_getprop(fmd.d_conf, "plugin.close", &doclose); 1087c478bd9Sstevel@tonic-gate if (doclose) 1097c478bd9Sstevel@tonic-gate err = dlclose(rp->rtld_dlp); 1107c478bd9Sstevel@tonic-gate 1117c478bd9Sstevel@tonic-gate fmd_free(rp, sizeof (fmd_rtld_t)); 1127c478bd9Sstevel@tonic-gate return (err); 1137c478bd9Sstevel@tonic-gate } 1147c478bd9Sstevel@tonic-gate 1157c478bd9Sstevel@tonic-gate const fmd_modops_t fmd_rtld_ops = { 1167c478bd9Sstevel@tonic-gate rtld_init, 1177c478bd9Sstevel@tonic-gate rtld_fini, 1187c478bd9Sstevel@tonic-gate fmd_module_dispatch, 119*d9638e54Smws fmd_module_transport, 1207c478bd9Sstevel@tonic-gate }; 121