SoW-2020-0002: Trace Hit Counters: trigger error reporting integration
[lttng-tools.git] / src / bin / lttng-sessiond / modprobe.c
CommitLineData
096102bd 1/*
ab5be9fa
MJ
2 * Copyright (C) 2011 David Goulet <dgoulet@efficios.com>
3 * Copyright (C) 2014 Jan Glauber <jan.glauber@gmail.com>
096102bd 4 *
ab5be9fa 5 * SPDX-License-Identifier: GPL-2.0-only
096102bd 6 *
096102bd
DG
7 */
8
d11b2027
MJ
9/**
10 * @file modprobe.c
11 *
12 * @brief modprobe related functions.
13 *
14 */
15
6c1c0768 16#define _LGPL_SOURCE
c9d42407 17#include <assert.h>
096102bd
DG
18#include <stdio.h>
19#include <stdlib.h>
20#include <sys/wait.h>
21
22#include <common/common.h>
fbb9748b 23#include <common/utils.h>
096102bd
DG
24
25#include "modprobe.h"
26#include "kern-modules.h"
e6142f2e 27#include "lttng-sessiond.h"
096102bd 28
ab57d7d3
JG
29#define LTTNG_MOD_REQUIRED 1
30#define LTTNG_MOD_OPTIONAL 0
31
32/* LTTng kernel tracer mandatory core modules list */
2463b787
JR
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 */
ab57d7d3 37struct kern_modules_param kern_modules_control_core[] = {
b53d4e59
SM
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" },
2463b787
JR
44 { (char *) "lttng-ring-buffer-trigger-client" },
45 { (char *) "lttng-counter-client-percpu-64-modular" },
46 { (char *) "lttng-counter-client-percpu-32-modular" },
ab57d7d3
JG
47};
48
3fa9646c 49/* LTTng kernel tracer probe modules list */
fbb9748b 50struct kern_modules_param kern_modules_probes_default[] = {
b53d4e59
SM
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" },
096102bd
DG
93};
94
fbb9748b
JG
95/* dynamic probe modules list */
96static struct kern_modules_param *probes;
97static int nr_probes;
c9d42407 98static int probes_capacity;
fbb9748b 99
234170ac
UTL
100#if HAVE_KMOD
101#include <libkmod.h>
866c17ce 102
d11b2027
MJ
103/**
104 * @brief Logging function for libkmod integration.
105 */
234170ac
UTL
106static 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}
866c17ce 118
d11b2027
MJ
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 */
866c17ce 128static int setup_kmod_ctx(struct kmod_ctx **ctx)
234170ac 129{
866c17ce 130 int ret = 0;
234170ac 131
866c17ce 132 *ctx = kmod_new(NULL, NULL);
234170ac
UTL
133 if (!ctx) {
134 PERROR("Unable to create kmod library context");
135 ret = -ENOMEM;
136 goto error;
137 }
138
866c17ce
MJ
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
146error:
147 return ret;
148}
149
d11b2027
MJ
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 */
866c17ce
MJ
163static 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 }
234170ac
UTL
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
0b1e16b8 183 ret = kmod_module_probe_insert_module(mod, 0,
234170ac 184 NULL, NULL, NULL, NULL);
0b1e16b8
MJ
185 if (ret == -EEXIST) {
186 DBG("Module %s is already loaded", modules[i].name);
187 ret = 0;
188 } else if (ret < 0) {
16c2e854
PP
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 }
234170ac
UTL
198 } else {
199 DBG("Modprobe successfully %s", modules[i].name);
4ad664a0 200 modules[i].loaded = true;
234170ac
UTL
201 }
202
203 kmod_module_unref(mod);
204 }
205
206error:
207 if (ctx) {
208 kmod_unref(ctx);
209 }
210 return ret;
211}
212
d11b2027
MJ
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 */
866c17ce
MJ
225static 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
d11b2027
MJ
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 */
866c17ce
MJ
261static 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
4ad664a0
JG
275 if (!modules[i].loaded) {
276 continue;
277 }
278
866c17ce
MJ
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
298error:
299 if (ctx) {
300 kmod_unref(ctx);
301 }
302}
303
234170ac
UTL
304#else /* HAVE_KMOD */
305
fbb9748b 306static int modprobe_lttng(struct kern_modules_param *modules,
234170ac 307 int entries, int required)
096102bd
DG
308{
309 int ret = 0, i;
310 char modprobe[256];
311
e23b81ed 312 for (i = 0; i < entries; i++) {
096102bd
DG
313 ret = snprintf(modprobe, sizeof(modprobe),
314 "/sbin/modprobe %s%s",
ab57d7d3 315 required ? "" : "-q ",
e23b81ed 316 modules[i].name);
096102bd
DG
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) {
16c2e854
PP
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 }
096102bd 343 } else {
ab57d7d3 344 DBG("Modprobe successfully %s", modules[i].name);
355d2778 345 modules[i].loaded = true;
096102bd
DG
346 }
347 }
348
349error:
350 return ret;
351}
352
35e090b7
MJ
353static 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--) {
4ad664a0
JG
360 if (!modules[i].loaded) {
361 continue;
362 }
35e090b7
MJ
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
866c17ce
MJ
385#endif /* HAVE_KMOD */
386
35e090b7
MJ
387/*
388 * Remove control kernel module(s) in reverse load order.
389 */
390void 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
397static 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 */
415void 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 */
427void modprobe_remove_lttng_all(void)
428{
429 modprobe_remove_lttng_data();
430 modprobe_remove_lttng_control();
431}
432
e23b81ed
JG
433/*
434 * Load control kernel module(s).
435 */
436int modprobe_lttng_control(void)
437{
ab57d7d3
JG
438 int ret;
439
440 ret = modprobe_lttng(kern_modules_control_core,
441 ARRAY_SIZE(kern_modules_control_core),
442 LTTNG_MOD_REQUIRED);
ab57d7d3 443 return ret;
e23b81ed 444}
ab57d7d3 445
c9d42407
PP
446/**
447 * Grow global list of probes (double capacity or set it to 1 if
448 * currently 0 and copy existing data).
096102bd 449 */
c9d42407 450static int grow_probes(void)
096102bd 451{
c9d42407
PP
452 int i;
453 struct kern_modules_param *tmp_probes;
fbb9748b 454
c9d42407
PP
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;
fbb9748b
JG
465 }
466
c9d42407
PP
467 /* Double size. */
468 probes_capacity *= 2;
469
470 tmp_probes = zmalloc(sizeof(*tmp_probes) * probes_capacity);
471 if (!tmp_probes) {
fbb9748b
JG
472 PERROR("malloc probe list");
473 return -ENOMEM;
474 }
475
c9d42407
PP
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 */
492static int append_list_to_probes(const char *list)
493{
494 char *next;
d3c04b7c 495 int ret;
44603c80 496 char *tmp_list, *cur_list;
c9d42407
PP
497
498 assert(list);
499
44603c80 500 cur_list = tmp_list = strdup(list);
c9d42407
PP
501 if (!tmp_list) {
502 PERROR("strdup temp list");
503 return -ENOMEM;
504 }
505
506 for (;;) {
fbb9748b 507 size_t name_len;
c9d42407 508 struct kern_modules_param *cur_mod;
fbb9748b 509
44603c80 510 next = strtok(cur_list, ",");
fbb9748b 511 if (!next) {
c9d42407 512 break;
fbb9748b 513 }
44603c80 514 cur_list = NULL;
fbb9748b
JG
515
516 /* filter leading spaces */
517 while (*next == ' ') {
518 next++;
519 }
520
c9d42407
PP
521 if (probes_capacity <= nr_probes) {
522 ret = grow_probes();
523 if (ret) {
398d5459 524 goto error;
c9d42407
PP
525 }
526 }
527
fbb9748b
JG
528 /* Length 13 is "lttng-probe-" + \0 */
529 name_len = strlen(next) + 13;
530
d3c04b7c 531 cur_mod = &probes[nr_probes];
c9d42407
PP
532 cur_mod->name = zmalloc(name_len);
533 if (!cur_mod->name) {
fbb9748b 534 PERROR("malloc probe list");
398d5459
MD
535 ret = -ENOMEM;
536 goto error;
fbb9748b
JG
537 }
538
c9d42407 539 ret = snprintf(cur_mod->name, name_len, "lttng-probe-%s", next);
fbb9748b
JG
540 if (ret < 0) {
541 PERROR("snprintf modprobe name");
398d5459
MD
542 ret = -ENOMEM;
543 goto error;
fbb9748b 544 }
c9d42407 545
c9d42407 546 nr_probes++;
fbb9748b
JG
547 }
548
c9d42407 549 free(tmp_list);
c9d42407 550 return 0;
398d5459
MD
551
552error:
553 free(tmp_list);
554 free_probes();
555 return ret;
c9d42407
PP
556}
557
558/*
559 * Load data kernel module(s).
560 */
561int 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 */
e6142f2e 570 list = config.kmod_probes_list.value;
c9d42407
PP
571 if (list) {
572 /* User-specified probes. */
573 ret = append_list_to_probes(list);
c9d42407
PP
574 if (ret) {
575 return ret;
576 }
577 } else {
578 /* Default probes. */
579 int def_len = ARRAY_SIZE(kern_modules_probes_default);
c9d42407 580
62e0422e 581 probes = zmalloc(sizeof(*probes) * def_len);
c9d42407
PP
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");
398d5459
MD
594 ret = -ENOMEM;
595 goto error;
c9d42407
PP
596 }
597
598 probes[i].name = name;
599 }
600 }
601
602 /*
603 * Extra modules? Append them to current probes list.
604 */
e6142f2e 605 list = config.kmod_extra_probes_list.value;
c9d42407
PP
606 if (list) {
607 ret = append_list_to_probes(list);
608 if (ret) {
398d5459 609 goto error;
c9d42407
PP
610 }
611 }
612
613 /*
614 * Load probes modules now.
615 */
398d5459
MD
616 ret = modprobe_lttng(probes, nr_probes, LTTNG_MOD_OPTIONAL);
617 if (ret) {
618 goto error;
619 }
620 return ret;
621
622error:
623 free_probes();
624 return ret;
096102bd 625}
This page took 0.161699 seconds and 5 git commands to generate.