* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#define _GNU_SOURCE
+#define _LGPL_SOURCE
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
{ "lttng-probe-v4l2" },
{ "lttng-probe-workqueue" },
{ "lttng-probe-writeback" },
+ { "lttng-probe-x86-irq-vectors" },
+ { "lttng-probe-x86-exceptions" },
};
/* dynamic probe modules list */
static int nr_probes;
static int probes_capacity;
-void modprobe_remove_lttng(const struct kern_modules_param *modules,
- int entries, int required)
+static void modprobe_remove_lttng(const struct kern_modules_param *modules,
+ int entries, int required)
{
int ret = 0, i;
char modprobe[256];
LTTNG_MOD_REQUIRED);
}
+static void free_probes(void)
+{
+ int i;
+
+ if (!probes) {
+ return;
+ }
+ for (i = 0; i < nr_probes; ++i) {
+ free(probes[i].name);
+ }
+ free(probes);
+ probes = NULL;
+ nr_probes = 0;
+}
+
/*
* Remove data kernel modules in reverse load order.
*/
void modprobe_remove_lttng_data(void)
{
- int i;
-
- if (probes) {
- modprobe_remove_lttng(probes, nr_probes, LTTNG_MOD_OPTIONAL);
-
- for (i = 0; i < nr_probes; ++i) {
- free(probes[i].name);
- }
-
- free(probes);
- probes = NULL;
+ if (!probes) {
+ return;
}
+ modprobe_remove_lttng(probes, nr_probes, LTTNG_MOD_OPTIONAL);
+ free_probes();
}
/*
ret = kmod_module_probe_insert_module(mod, KMOD_PROBE_IGNORE_LOADED,
NULL, NULL, NULL, NULL);
- if (required && ret < 0) {
- ERR("Unable to load module %s", modules[i].name);
+ if (ret < 0) {
+ if (required) {
+ ERR("Unable to load required module %s",
+ modules[i].name);
+ goto error;
+ } else {
+ DBG("Unable to load optional module %s; continuing",
+ modules[i].name);
+ ret = 0;
+ }
} else {
DBG("Modprobe successfully %s", modules[i].name);
}
modprobe[sizeof(modprobe) - 1] = '\0';
ret = system(modprobe);
if (ret == -1) {
- ERR("Unable to launch modprobe for module %s",
- modules[i].name);
- } else if (required && WEXITSTATUS(ret) != 0) {
- ERR("Unable to load module %s", modules[i].name);
+ if (required) {
+ ERR("Unable to launch modprobe for required module %s",
+ modules[i].name);
+ goto error;
+ } else {
+ DBG("Unable to launch modprobe for optional module %s; continuing",
+ modules[i].name);
+ ret = 0;
+ }
+ } else if (WEXITSTATUS(ret) != 0) {
+ if (required) {
+ ERR("Unable to load required module %s",
+ modules[i].name);
+ goto error;
+ } else {
+ DBG("Unable to load optional module %s; continuing",
+ modules[i].name);
+ ret = 0;
+ }
} else {
DBG("Modprobe successfully %s", modules[i].name);
}
static int append_list_to_probes(const char *list)
{
char *next;
- int index = nr_probes, ret;
+ int ret;
+ char *tmp_list, *cur_list;
assert(list);
- char *tmp_list = strdup(list);
+ cur_list = tmp_list = strdup(list);
if (!tmp_list) {
PERROR("strdup temp list");
return -ENOMEM;
size_t name_len;
struct kern_modules_param *cur_mod;
- next = strtok(tmp_list, ",");
+ next = strtok(cur_list, ",");
if (!next) {
break;
}
- tmp_list = NULL;
+ cur_list = NULL;
/* filter leading spaces */
while (*next == ' ') {
if (probes_capacity <= nr_probes) {
ret = grow_probes();
if (ret) {
- return ret;
+ goto error;
}
}
/* Length 13 is "lttng-probe-" + \0 */
name_len = strlen(next) + 13;
- cur_mod = &probes[index];
+ cur_mod = &probes[nr_probes];
cur_mod->name = zmalloc(name_len);
if (!cur_mod->name) {
PERROR("malloc probe list");
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto error;
}
ret = snprintf(cur_mod->name, name_len, "lttng-probe-%s", next);
if (ret < 0) {
PERROR("snprintf modprobe name");
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto error;
}
- cur_mod++;
nr_probes++;
}
free(tmp_list);
-
return 0;
+
+error:
+ free(tmp_list);
+ free_probes();
+ return ret;
}
/*
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);
+ probes = zmalloc(sizeof(*probes) * def_len);
if (!probes) {
PERROR("malloc probe list");
return -ENOMEM;
if (!name) {
PERROR("strdup probe item");
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto error;
}
probes[i].name = name;
if (list) {
ret = append_list_to_probes(list);
if (ret) {
- return ret;
+ goto error;
}
}
/*
* Load probes modules now.
*/
- return modprobe_lttng(probes, nr_probes, LTTNG_MOD_OPTIONAL);
+ ret = modprobe_lttng(probes, nr_probes, LTTNG_MOD_OPTIONAL);
+ if (ret) {
+ goto error;
+ }
+ return ret;
+
+error:
+ free_probes();
+ return ret;
}