/** * Unload decoder module. * * @param dec The struct srd_decoder to be unloaded. * * @return SRD_OK upon success, a (negative) error code otherwise. */ SRD_API int srd_decoder_unload(struct srd_decoder *dec) { srd_dbg("Unloading protocol decoder '%s'.", dec->name); /* * Since any instances of this decoder need to be released as well, * but they could be anywhere in the stack, just free the entire * stack. A frontend reloading a decoder thus has to restart all * instances, and rebuild the stack. */ srd_inst_free_all(NULL); free_probes(dec->probes); free_probes(dec->opt_probes); g_free(dec->id); g_free(dec->name); g_free(dec->longname); g_free(dec->desc); g_free(dec->license); /* The module's Decoder class. */ Py_XDECREF(dec->py_dec); /* The module itself. */ Py_XDECREF(dec->py_mod); /* TODO: (g_)free dec itself? */ return SRD_OK; }
/* * Remove data kernel modules in reverse load order. */ void modprobe_remove_lttng_data(void) { if (!probes) { return; } modprobe_remove_lttng(probes, nr_probes, LTTNG_MOD_OPTIONAL); free_probes(); }
/* * Load data kernel module(s). */ int modprobe_lttng_data(void) { int ret, i; char *list; /* * Base probes: either from command line option, environment * variable or default list. */ if (kmod_probes_list) { list = kmod_probes_list; } else { list = utils_get_kmod_probes_list(); } if (list) { /* User-specified probes. */ ret = append_list_to_probes(list); if (ret) { return ret; } } else { /* Default probes. */ int def_len = ARRAY_SIZE(kern_modules_probes_default); probes = zmalloc(sizeof(*probes) * def_len); if (!probes) { PERROR("malloc probe list"); return -ENOMEM; } nr_probes = probes_capacity = def_len; for (i = 0; i < def_len; ++i) { char* name = strdup(kern_modules_probes_default[i].name); if (!name) { PERROR("strdup probe item"); ret = -ENOMEM; goto error; } probes[i].name = name; } } /* * Extra modules? Append them to current probes list. */ if (kmod_extra_probes_list) { list = kmod_extra_probes_list; } else { list = utils_get_extra_kmod_probes_list(); } if (list) { ret = append_list_to_probes(list); if (ret) { goto error; } } /* * Load probes modules now. */ ret = modprobe_lttng(probes, nr_probes, LTTNG_MOD_OPTIONAL); if (ret) { goto error; } return ret; error: free_probes(); return ret; }
/* * Appends a comma-separated list of probes to the global list * of probes. */ static int append_list_to_probes(const char *list) { char *next; int index = nr_probes, ret; char *tmp_list; assert(list); tmp_list = strdup(list); if (!tmp_list) { PERROR("strdup temp list"); return -ENOMEM; } for (;;) { size_t name_len; struct kern_modules_param *cur_mod; next = strtok(tmp_list, ","); if (!next) { break; } tmp_list = NULL; /* filter leading spaces */ while (*next == ' ') { next++; } if (probes_capacity <= nr_probes) { ret = grow_probes(); if (ret) { goto error; } } /* Length 13 is "lttng-probe-" + \0 */ name_len = strlen(next) + 13; cur_mod = &probes[index]; cur_mod->name = zmalloc(name_len); if (!cur_mod->name) { PERROR("malloc probe list"); ret = -ENOMEM; goto error; } ret = snprintf(cur_mod->name, name_len, "lttng-probe-%s", next); if (ret < 0) { PERROR("snprintf modprobe name"); ret = -ENOMEM; goto error; } cur_mod++; nr_probes++; } free(tmp_list); return 0; error: free(tmp_list); free_probes(); return ret; }