1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright (c) 1994, by Sun Microsytems, Inc. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 /* 29 * Interface to close a tnfctl handle 30 */ 31 32 #include "tnfctl_int.h" 33 #include "kernel_int.h" 34 #include "dbg.h" 35 36 #include <stdlib.h> 37 #include <signal.h> 38 #include <errno.h> 39 40 /* for bug 1253419 - guard against multiple tracing */ 41 42 extern mutex_t _tnfctl_internalguard_lock; 43 44 /* 45 * Close a tnfctl handle - close any open fds and free up any memory 46 * that was allocated. 47 */ 48 tnfctl_errcode_t 49 tnfctl_close(tnfctl_handle_t *hdl, tnfctl_targ_op_t action) 50 { 51 tnfctl_errcode_t prexstat; 52 prb_status_t prbstat; 53 prb_proc_ctl_t *proc_p; 54 tnfctl_probe_t *probe_hdl, *tmp_hdl; 55 56 if (hdl == NULL) 57 return (TNFCTL_ERR_NONE); 58 59 if (hdl->mode == KERNEL_MODE) { 60 prexstat = _tnfctl_prbk_close(hdl); 61 if (prexstat) 62 return (prexstat); 63 } 64 65 if (hdl->mode == INTERNAL_MODE) { 66 _tnfctl_internal_releaselock(); 67 } else if (hdl->mode != KERNEL_MODE) { 68 _tnfctl_external_releaselock(hdl); 69 } 70 71 _tnfctl_free_objs_and_probes(hdl); 72 73 /* free probe handles */ 74 probe_hdl = hdl->probe_handle_list_head; 75 while (probe_hdl != NULL) { 76 /* call the destructor function for client probe data */ 77 if (hdl->destroy_func) 78 hdl->destroy_func(probe_hdl->client_registered_data); 79 tmp_hdl = probe_hdl; 80 probe_hdl = probe_hdl->next; 81 free(tmp_hdl); 82 } 83 hdl->probe_handle_list_head = NULL; 84 85 if (hdl->mode != DIRECT_MODE) { 86 /* indirect, internal, or kernel mode */ 87 free(hdl); 88 return (TNFCTL_ERR_NONE); 89 } 90 91 /* DIRECT_MODE */ 92 93 proc_p = hdl->proc_p; 94 if (proc_p == NULL) { 95 free(hdl); 96 return (TNFCTL_ERR_NONE); 97 } 98 99 switch (action) { 100 case TNFCTL_TARG_DEFAULT: 101 break; 102 case TNFCTL_TARG_KILL: 103 prbstat = prb_proc_setklc(proc_p, B_TRUE); 104 if (prbstat) 105 return (_tnfctl_map_to_errcode(prbstat)); 106 prbstat = prb_proc_setrlc(proc_p, B_FALSE); 107 if (prbstat) 108 return (_tnfctl_map_to_errcode(prbstat)); 109 break; 110 case TNFCTL_TARG_RESUME: 111 prbstat = prb_proc_setklc(proc_p, B_FALSE); 112 if (prbstat) 113 return (_tnfctl_map_to_errcode(prbstat)); 114 prbstat = prb_proc_setrlc(proc_p, B_TRUE); 115 if (prbstat) 116 return (_tnfctl_map_to_errcode(prbstat)); 117 break; 118 case TNFCTL_TARG_SUSPEND: 119 prbstat = prb_proc_setklc(proc_p, B_FALSE); 120 if (prbstat) 121 return (_tnfctl_map_to_errcode(prbstat)); 122 prbstat = prb_proc_setrlc(proc_p, B_FALSE); 123 if (prbstat) 124 return (_tnfctl_map_to_errcode(prbstat)); 125 break; 126 default: 127 return (TNFCTL_ERR_BADARG); 128 } 129 prbstat = prb_proc_close(proc_p); 130 free(hdl); 131 return (_tnfctl_map_to_errcode(prbstat)); 132 } 133 134 tnfctl_errcode_t 135 _tnfctl_internal_releaselock() 136 { 137 mutex_lock(&_tnfctl_internalguard_lock); 138 _tnfctl_internal_tracing_flag = 0; 139 mutex_unlock(&_tnfctl_internalguard_lock); 140 return (TNFCTL_ERR_NONE); 141 } 142 143 tnfctl_errcode_t 144 _tnfctl_external_releaselock(tnfctl_handle_t *hdl) 145 { 146 tnfctl_errcode_t prexstat; 147 prb_status_t prbstat; 148 uintptr_t targ_symbol_ptr; 149 pid_t pidzero = 0; 150 151 prexstat = _tnfctl_sym_find(hdl, TNFCTL_EXTERNAL_TRACEDPID, 152 &targ_symbol_ptr); 153 if (prexstat) { 154 return (prexstat); 155 } 156 prbstat = hdl->p_write(hdl->proc_p, targ_symbol_ptr, 157 &pidzero, sizeof (pidzero)); 158 if (prbstat) { 159 return (_tnfctl_map_to_errcode(prbstat)); 160 } 161 return (TNFCTL_ERR_NONE); 162 } 163