SoW-2020-0002: Trace Hit Counters: trigger error reporting integration
[lttng-tools.git] / src / bin / lttng-sessiond / modprobe.c
1 /*
2 * Copyright (C) 2011 David Goulet <dgoulet@efficios.com>
3 * Copyright (C) 2014 Jan Glauber <jan.glauber@gmail.com>
4 *
5 * SPDX-License-Identifier: GPL-2.0-only
6 *
7 */
8
9 /**
10 * @file modprobe.c
11 *
12 * @brief modprobe related functions.
13 *
14 */
15
16 #define _LGPL_SOURCE
17 #include <assert.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <sys/wait.h>
21
22 #include <common/common.h>
23 #include <common/utils.h>
24
25 #include "modprobe.h"
26 #include "kern-modules.h"
27 #include "lttng-sessiond.h"
28
29 #define LTTNG_MOD_REQUIRED 1
30 #define LTTNG_MOD_OPTIONAL 0
31
32 /* LTTng kernel tracer mandatory core modules list */
33 /* TODO: the new trigger client might not be present in previous lttng-modules
34 * should it be optional?
35 * Can we reuse this to also know of the trigger feature is supported?
36 */
37 struct kern_modules_param kern_modules_control_core[] = {
38 { (char *) "lttng-ring-buffer-client-discard" },
39 { (char *) "lttng-ring-buffer-client-overwrite" },
40 { (char *) "lttng-ring-buffer-metadata-client" },
41 { (char *) "lttng-ring-buffer-client-mmap-discard" },
42 { (char *) "lttng-ring-buffer-client-mmap-overwrite" },
43 { (char *) "lttng-ring-buffer-metadata-mmap-client" },
44 { (char *) "lttng-ring-buffer-trigger-client" },
45 { (char *) "lttng-counter-client-percpu-64-modular" },
46 { (char *) "lttng-counter-client-percpu-32-modular" },
47 };
48
49 /* LTTng kernel tracer probe modules list */
50 struct kern_modules_param kern_modules_probes_default[] = {
51 { (char *) "lttng-probe-asoc" },
52 { (char *) "lttng-probe-block" },
53 { (char *) "lttng-probe-btrfs" },
54 { (char *) "lttng-probe-compaction" },
55 { (char *) "lttng-probe-ext3" },
56 { (char *) "lttng-probe-ext4" },
57 { (char *) "lttng-probe-gpio" },
58 { (char *) "lttng-probe-i2c" },
59 { (char *) "lttng-probe-irq" },
60 { (char *) "lttng-probe-jbd" },
61 { (char *) "lttng-probe-jbd2" },
62 { (char *) "lttng-probe-kmem" },
63 { (char *) "lttng-probe-kvm" },
64 { (char *) "lttng-probe-kvm-x86" },
65 { (char *) "lttng-probe-kvm-x86-mmu" },
66 { (char *) "lttng-probe-lock" },
67 { (char *) "lttng-probe-module" },
68 { (char *) "lttng-probe-napi" },
69 { (char *) "lttng-probe-net" },
70 { (char *) "lttng-probe-power" },
71 { (char *) "lttng-probe-preemptirq" },
72 { (char *) "lttng-probe-printk" },
73 { (char *) "lttng-probe-random" },
74 { (char *) "lttng-probe-rcu" },
75 { (char *) "lttng-probe-regmap" },
76 { (char *) "lttng-probe-regulator" },
77 { (char *) "lttng-probe-rpm" },
78 { (char *) "lttng-probe-sched" },
79 { (char *) "lttng-probe-scsi" },
80 { (char *) "lttng-probe-signal" },
81 { (char *) "lttng-probe-skb" },
82 { (char *) "lttng-probe-sock" },
83 { (char *) "lttng-probe-statedump" },
84 { (char *) "lttng-probe-sunrpc" },
85 { (char *) "lttng-probe-timer" },
86 { (char *) "lttng-probe-udp" },
87 { (char *) "lttng-probe-vmscan" },
88 { (char *) "lttng-probe-v4l2" },
89 { (char *) "lttng-probe-workqueue" },
90 { (char *) "lttng-probe-writeback" },
91 { (char *) "lttng-probe-x86-irq-vectors" },
92 { (char *) "lttng-probe-x86-exceptions" },
93 };
94
95 /* dynamic probe modules list */
96 static struct kern_modules_param *probes;
97 static int nr_probes;
98 static int probes_capacity;
99
100 #if HAVE_KMOD
101 #include <libkmod.h>
102
103 /**
104 * @brief Logging function for libkmod integration.
105 */
106 static void log_kmod(void *data, int priority, const char *file, int line,
107 const char *fn, const char *format, va_list args)
108 {
109 char *str;
110
111 if (vasprintf(&str, format, args) < 0) {
112 return;
113 }
114
115 DBG("libkmod: %s", str);
116 free(str);
117 }
118
119 /**
120 * @brief Setup the libkmod context.
121 *
122 * Create the context, add a custom logging function and preload the
123 * ressources for faster operation.
124 *
125 * @returns \c 0 on success
126 * \c < 0 on error
127 */
128 static int setup_kmod_ctx(struct kmod_ctx **ctx)
129 {
130 int ret = 0;
131
132 *ctx = kmod_new(NULL, NULL);
133 if (!ctx) {
134 PERROR("Unable to create kmod library context");
135 ret = -ENOMEM;
136 goto error;
137 }
138
139 kmod_set_log_fn(*ctx, log_kmod, NULL);
140 ret = kmod_load_resources(*ctx);
141 if (ret < 0) {
142 ERR("Failed to load kmod library resources");
143 goto error;
144 }
145
146 error:
147 return ret;
148 }
149
150 /**
151 * @brief Loads the kernel modules in \p modules
152 *
153 * @param modules List of modules to load
154 * @param entries Number of modules in the list
155 * @param required Are the modules required or optionnal
156 *
157 * If the modules are required, we will return with error after the
158 * first failed module load, otherwise we continue loading.
159 *
160 * @returns \c 0 on success
161 * \c < 0 on error
162 */
163 static int modprobe_lttng(struct kern_modules_param *modules,
164 int entries, int required)
165 {
166 int ret = 0, i;
167 struct kmod_ctx *ctx;
168
169 ret = setup_kmod_ctx(&ctx);
170 if (ret < 0) {
171 goto error;
172 }
173
174 for (i = 0; i < entries; i++) {
175 struct kmod_module *mod = NULL;
176
177 ret = kmod_module_new_from_name(ctx, modules[i].name, &mod);
178 if (ret < 0) {
179 PERROR("Failed to create kmod module for %s", modules[i].name);
180 goto error;
181 }
182
183 ret = kmod_module_probe_insert_module(mod, 0,
184 NULL, NULL, NULL, NULL);
185 if (ret == -EEXIST) {
186 DBG("Module %s is already loaded", modules[i].name);
187 ret = 0;
188 } else if (ret < 0) {
189 if (required) {
190 ERR("Unable to load required module %s",
191 modules[i].name);
192 goto error;
193 } else {
194 DBG("Unable to load optional module %s; continuing",
195 modules[i].name);
196 ret = 0;
197 }
198 } else {
199 DBG("Modprobe successfully %s", modules[i].name);
200 modules[i].loaded = true;
201 }
202
203 kmod_module_unref(mod);
204 }
205
206 error:
207 if (ctx) {
208 kmod_unref(ctx);
209 }
210 return ret;
211 }
212
213 /**
214 * @brief Recursively unload modules.
215 *
216 * This function implements the same modules unloading behavior as
217 * 'modprobe -r' or rmmod, it will recursevily go trought the \p module
218 * dependencies and unload modules with a refcount of 0.
219 *
220 * @param mod The module to unload
221 *
222 * @returns \c 0 on success
223 * \c < 0 on error
224 */
225 static int rmmod_recurse(struct kmod_module *mod) {
226 int ret = 0;
227 struct kmod_list *deps, *itr;
228
229 if (kmod_module_get_initstate(mod) == KMOD_MODULE_BUILTIN) {
230 DBG("Module %s is builtin", kmod_module_get_name(mod));
231 return ret;
232 }
233
234 ret = kmod_module_remove_module(mod, 0);
235
236 deps = kmod_module_get_dependencies(mod);
237 if (deps != NULL) {
238 kmod_list_foreach(itr, deps) {
239 struct kmod_module *dep = kmod_module_get_module(itr);
240 if (kmod_module_get_refcnt(dep) == 0) {
241 DBG("Recursive remove module %s",
242 kmod_module_get_name(dep));
243 rmmod_recurse(dep);
244 }
245 kmod_module_unref(dep);
246 }
247 kmod_module_unref_list(deps);
248 }
249
250 return ret;
251 }
252
253 /**
254 * @brief Unloads the kernel modules in \p modules
255 *
256 * @param modules List of modules to unload
257 * @param entries Number of modules in the list
258 * @param required Are the modules required or optionnal
259 *
260 */
261 static void modprobe_remove_lttng(const struct kern_modules_param *modules,
262 int entries, int required)
263 {
264 int ret = 0, i;
265 struct kmod_ctx *ctx;
266
267 ret = setup_kmod_ctx(&ctx);
268 if (ret < 0) {
269 goto error;
270 }
271
272 for (i = entries - 1; i >= 0; i--) {
273 struct kmod_module *mod = NULL;
274
275 if (!modules[i].loaded) {
276 continue;
277 }
278
279 ret = kmod_module_new_from_name(ctx, modules[i].name, &mod);
280 if (ret < 0) {
281 PERROR("Failed to create kmod module for %s", modules[i].name);
282 goto error;
283 }
284
285 ret = rmmod_recurse(mod);
286 if (ret == -EEXIST) {
287 DBG("Module %s is not in kernel.", modules[i].name);
288 } else if (required && ret < 0) {
289 ERR("Unable to remove module %s", modules[i].name);
290 } else {
291 DBG("Modprobe removal successful %s",
292 modules[i].name);
293 }
294
295 kmod_module_unref(mod);
296 }
297
298 error:
299 if (ctx) {
300 kmod_unref(ctx);
301 }
302 }
303
304 #else /* HAVE_KMOD */
305
306 static int modprobe_lttng(struct kern_modules_param *modules,
307 int entries, int required)
308 {
309 int ret = 0, i;
310 char modprobe[256];
311
312 for (i = 0; i < entries; i++) {
313 ret = snprintf(modprobe, sizeof(modprobe),
314 "/sbin/modprobe %s%s",
315 required ? "" : "-q ",
316 modules[i].name);
317 if (ret < 0) {
318 PERROR("snprintf modprobe");
319 goto error;
320 }
321 modprobe[sizeof(modprobe) - 1] = '\0';
322 ret = system(modprobe);
323 if (ret == -1) {
324 if (required) {
325 ERR("Unable to launch modprobe for required module %s",
326 modules[i].name);
327 goto error;
328 } else {
329 DBG("Unable to launch modprobe for optional module %s; continuing",
330 modules[i].name);
331 ret = 0;
332 }
333 } else if (WEXITSTATUS(ret) != 0) {
334 if (required) {
335 ERR("Unable to load required module %s",
336 modules[i].name);
337 goto error;
338 } else {
339 DBG("Unable to load optional module %s; continuing",
340 modules[i].name);
341 ret = 0;
342 }
343 } else {
344 DBG("Modprobe successfully %s", modules[i].name);
345 modules[i].loaded = true;
346 }
347 }
348
349 error:
350 return ret;
351 }
352
353 static void modprobe_remove_lttng(const struct kern_modules_param *modules,
354 int entries, int required)
355 {
356 int ret = 0, i;
357 char modprobe[256];
358
359 for (i = entries - 1; i >= 0; i--) {
360 if (!modules[i].loaded) {
361 continue;
362 }
363 ret = snprintf(modprobe, sizeof(modprobe),
364 "/sbin/modprobe -r -q %s",
365 modules[i].name);
366 if (ret < 0) {
367 PERROR("snprintf modprobe -r");
368 return;
369 }
370 modprobe[sizeof(modprobe) - 1] = '\0';
371 ret = system(modprobe);
372 if (ret == -1) {
373 ERR("Unable to launch modprobe -r for module %s",
374 modules[i].name);
375 } else if (required && WEXITSTATUS(ret) != 0) {
376 ERR("Unable to remove module %s",
377 modules[i].name);
378 } else {
379 DBG("Modprobe removal successful %s",
380 modules[i].name);
381 }
382 }
383 }
384
385 #endif /* HAVE_KMOD */
386
387 /*
388 * Remove control kernel module(s) in reverse load order.
389 */
390 void modprobe_remove_lttng_control(void)
391 {
392 modprobe_remove_lttng(kern_modules_control_core,
393 ARRAY_SIZE(kern_modules_control_core),
394 LTTNG_MOD_REQUIRED);
395 }
396
397 static void free_probes(void)
398 {
399 int i;
400
401 if (!probes) {
402 return;
403 }
404 for (i = 0; i < nr_probes; ++i) {
405 free(probes[i].name);
406 }
407 free(probes);
408 probes = NULL;
409 nr_probes = 0;
410 }
411
412 /*
413 * Remove data kernel modules in reverse load order.
414 */
415 void modprobe_remove_lttng_data(void)
416 {
417 if (!probes) {
418 return;
419 }
420 modprobe_remove_lttng(probes, nr_probes, LTTNG_MOD_OPTIONAL);
421 free_probes();
422 }
423
424 /*
425 * Remove all kernel modules in reverse order.
426 */
427 void modprobe_remove_lttng_all(void)
428 {
429 modprobe_remove_lttng_data();
430 modprobe_remove_lttng_control();
431 }
432
433 /*
434 * Load control kernel module(s).
435 */
436 int modprobe_lttng_control(void)
437 {
438 int ret;
439
440 ret = modprobe_lttng(kern_modules_control_core,
441 ARRAY_SIZE(kern_modules_control_core),
442 LTTNG_MOD_REQUIRED);
443 return ret;
444 }
445
446 /**
447 * Grow global list of probes (double capacity or set it to 1 if
448 * currently 0 and copy existing data).
449 */
450 static int grow_probes(void)
451 {
452 int i;
453 struct kern_modules_param *tmp_probes;
454
455 /* Initialize capacity to 1 if 0. */
456 if (probes_capacity == 0) {
457 probes = zmalloc(sizeof(*probes));
458 if (!probes) {
459 PERROR("malloc probe list");
460 return -ENOMEM;
461 }
462
463 probes_capacity = 1;
464 return 0;
465 }
466
467 /* Double size. */
468 probes_capacity *= 2;
469
470 tmp_probes = zmalloc(sizeof(*tmp_probes) * probes_capacity);
471 if (!tmp_probes) {
472 PERROR("malloc probe list");
473 return -ENOMEM;
474 }
475
476 for (i = 0; i < nr_probes; ++i) {
477 /* Move name pointer. */
478 tmp_probes[i].name = probes[i].name;
479 }
480
481 /* Replace probes with larger copy. */
482 free(probes);
483 probes = tmp_probes;
484
485 return 0;
486 }
487
488 /*
489 * Appends a comma-separated list of probes to the global list
490 * of probes.
491 */
492 static int append_list_to_probes(const char *list)
493 {
494 char *next;
495 int ret;
496 char *tmp_list, *cur_list;
497
498 assert(list);
499
500 cur_list = tmp_list = strdup(list);
501 if (!tmp_list) {
502 PERROR("strdup temp list");
503 return -ENOMEM;
504 }
505
506 for (;;) {
507 size_t name_len;
508 struct kern_modules_param *cur_mod;
509
510 next = strtok(cur_list, ",");
511 if (!next) {
512 break;
513 }
514 cur_list = NULL;
515
516 /* filter leading spaces */
517 while (*next == ' ') {
518 next++;
519 }
520
521 if (probes_capacity <= nr_probes) {
522 ret = grow_probes();
523 if (ret) {
524 goto error;
525 }
526 }
527
528 /* Length 13 is "lttng-probe-" + \0 */
529 name_len = strlen(next) + 13;
530
531 cur_mod = &probes[nr_probes];
532 cur_mod->name = zmalloc(name_len);
533 if (!cur_mod->name) {
534 PERROR("malloc probe list");
535 ret = -ENOMEM;
536 goto error;
537 }
538
539 ret = snprintf(cur_mod->name, name_len, "lttng-probe-%s", next);
540 if (ret < 0) {
541 PERROR("snprintf modprobe name");
542 ret = -ENOMEM;
543 goto error;
544 }
545
546 nr_probes++;
547 }
548
549 free(tmp_list);
550 return 0;
551
552 error:
553 free(tmp_list);
554 free_probes();
555 return ret;
556 }
557
558 /*
559 * Load data kernel module(s).
560 */
561 int modprobe_lttng_data(void)
562 {
563 int ret, i;
564 char *list;
565
566 /*
567 * Base probes: either from command line option, environment
568 * variable or default list.
569 */
570 list = config.kmod_probes_list.value;
571 if (list) {
572 /* User-specified probes. */
573 ret = append_list_to_probes(list);
574 if (ret) {
575 return ret;
576 }
577 } else {
578 /* Default probes. */
579 int def_len = ARRAY_SIZE(kern_modules_probes_default);
580
581 probes = zmalloc(sizeof(*probes) * def_len);
582 if (!probes) {
583 PERROR("malloc probe list");
584 return -ENOMEM;
585 }
586
587 nr_probes = probes_capacity = def_len;
588
589 for (i = 0; i < def_len; ++i) {
590 char* name = strdup(kern_modules_probes_default[i].name);
591
592 if (!name) {
593 PERROR("strdup probe item");
594 ret = -ENOMEM;
595 goto error;
596 }
597
598 probes[i].name = name;
599 }
600 }
601
602 /*
603 * Extra modules? Append them to current probes list.
604 */
605 list = config.kmod_extra_probes_list.value;
606 if (list) {
607 ret = append_list_to_probes(list);
608 if (ret) {
609 goto error;
610 }
611 }
612
613 /*
614 * Load probes modules now.
615 */
616 ret = modprobe_lttng(probes, nr_probes, LTTNG_MOD_OPTIONAL);
617 if (ret) {
618 goto error;
619 }
620 return ret;
621
622 error:
623 free_probes();
624 return ret;
625 }
This page took 0.068193 seconds and 5 git commands to generate.