/* stapkp_refresh is called for two reasons: either a kprobe needs to be * enabled/disabled (modname is NULL), or a module has been loaded/unloaded and * kprobes need to be registered/unregistered (modname is !NULL). */ static void stapkp_refresh(const char *modname, struct stap_dwarf_probe *probes, size_t nprobes) { size_t i; for (i = 0; i < nprobes; i++) { struct stap_dwarf_probe *sdp = &probes[i]; // was this probe's target module loaded/unloaded if (modname && sdp->module && strcmp(modname, sdp->module) == 0) { int rc; unsigned long addr = stapkp_relocate_addr(sdp); // module being loaded? if (sdp->registered_p == 0 && addr != 0) stapkp_register_probe(sdp); // module/section being unloaded? else if (sdp->registered_p == 1 && addr == 0) stapkp_unregister_probe(sdp); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30) } else if (stapkp_should_enable_probe(sdp) || stapkp_should_disable_probe(sdp)) { stapkp_refresh_probe(sdp); #endif } } }
static void stapkp_unregister_probes(struct stap_dwarf_probe *probes, size_t nprobes) { #if defined(STAPCONF_UNREGISTER_KPROBES) // Unregister using batch mode stapkp_batch_unregister_probes(probes, nprobes); #else // We'll have to unregister them one by one size_t i; for (i = 0; i < nprobes; i++) { struct stap_dwarf_probe *sdp = &probes[i]; if (!sdp->registered_p) continue; stapkp_unregister_probe(sdp); } #endif }
static int stapkp_disable_probe(struct stap_dwarf_probe *sdp) { int ret = 0; dbug_otf("disabling (k%sprobe) pidx %zu\n", sdp->return_p ? "ret" : "", sdp->probe->index); ret = sdp->return_p ? disable_kretprobe(&sdp->kprobe->u.krp) : disable_kprobe(&sdp->kprobe->u.kp); if (ret != 0) { stapkp_unregister_probe(sdp); dbug_otf("failed to disable (k%sprobe) pidx %zu (rc %d)\n", sdp->return_p ? "ret" : "", sdp->probe->index, ret); } return ret; }
static int stapkp_enable_probe(struct stap_kprobe_probe *skp) { int ret = 0; dbug_otf("enabling (k%sprobe) pidx %zu\n", skp->return_p ? "ret" : "", skp->probe->index); ret = skp->return_p ? enable_kretprobe(&skp->kprobe->u.krp) : enable_kprobe(&skp->kprobe->u.kp); if (ret != 0) { stapkp_unregister_probe(skp); dbug_otf("failed to enable (k%sprobe) pidx %zu (rc %d)\n", skp->return_p ? "ret" : "", skp->probe->index, ret); } return ret; }
/* stapkp_refresh is called for two reasons: either a kprobe needs to be * enabled/disabled (modname is NULL), or a module has been loaded/unloaded and * kprobes need to be registered/unregistered (modname is !NULL). */ static void stapkp_refresh(const char *modname, struct stap_kprobe_probe *probes, size_t nprobes) { size_t i; dbug_stapkp("refresh %lu probes with module %s\n", nprobes, modname ?: "?"); #ifdef STAPCONF_KALLSYMS_ON_EACH_SYMBOL if (modname) { size_t probe_max = 0; for (i = 0; i < nprobes; i++) { struct stap_kprobe_probe *skp = &probes[i]; // If this probe is in the same module that is being // loaded/unloaded and the probe is symbol_name+offset based // and it isn't registered (so the module must be loaded), // try to convert all probes in the same module to // address-based probes. if (skp->module && strcmp(modname, skp->module) == 0 && skp->symbol_name && skp->registered_p == 0) ++probe_max; } if (probe_max > 0) { struct stapkp_symbol_data sd; sd.probes = probes; sd.nprobes = nprobes; sd.probe_max = probe_max; sd.modname = modname; preempt_disable(); kallsyms_on_each_symbol(stapkp_symbol_callback, &sd); preempt_enable(); } } #endif for (i = 0; i < nprobes; i++) { struct stap_kprobe_probe *skp = &probes[i]; // was this probe's target module loaded/unloaded if (modname && skp->module && strcmp(modname, skp->module) == 0) { int rc; unsigned long addr = (! skp->symbol_name ? stapkp_relocate_addr(skp) : 0); // module being loaded? if (skp->registered_p == 0 && (addr != 0 || skp->symbol_name)) stapkp_register_probe(skp); // module/section being unloaded? else if (skp->registered_p == 1 && addr == 0) stapkp_unregister_probe(skp); } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30) else if (stapkp_should_enable_probe(skp) || stapkp_should_disable_probe(skp)) { stapkp_refresh_probe(skp); } #endif } }