Prepare for '-Wignored-qualifiers'
[lttng-tools.git] / src / bin / lttng-sessiond / modprobe.cpp
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
096102bd
DG
17#include <stdio.h>
18#include <stdlib.h>
19#include <sys/wait.h>
20
21#include <common/common.h>
fbb9748b 22#include <common/utils.h>
096102bd
DG
23
24#include "modprobe.h"
25#include "kern-modules.h"
e6142f2e 26#include "lttng-sessiond.h"
096102bd 27
ab57d7d3
JG
28/* LTTng kernel tracer mandatory core modules list */
29struct kern_modules_param kern_modules_control_core[] = {
adfe4f5e
JG
30 {
31 .name = (char *) "lttng-ring-buffer-client-discard",
32 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_REQUIRED,
33 },
34 {
35 .name = (char *) "lttng-ring-buffer-client-overwrite",
36 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_REQUIRED,
37 },
38 {
39 .name = (char *) "lttng-ring-buffer-metadata-client",
40 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_REQUIRED,
41 },
42 {
43 .name = (char *) "lttng-ring-buffer-client-mmap-discard",
44 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_REQUIRED,
45 },
46 {
47 .name = (char *) "lttng-ring-buffer-client-mmap-overwrite",
48 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_REQUIRED,
49 },
50 {
51 .name = (char *) "lttng-ring-buffer-metadata-mmap-client",
52 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_REQUIRED,
53 },
87a15032
JR
54 {
55 .name = (char *) "lttng-ring-buffer-event_notifier-client",
56 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
57 },
90aa04a1
FD
58 {
59 .name = (char *) "lttng-counter-client-percpu-64-modular",
60 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
61 },
62 {
63 .name = (char *) "lttng-counter-client-percpu-32-modular",
64 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
65 },
ab57d7d3
JG
66};
67
adfe4f5e 68/* LTTng kerneltracer probe modules list */
fbb9748b 69struct kern_modules_param kern_modules_probes_default[] = {
adfe4f5e
JG
70 {
71 .name = (char *) "lttng-probe-asoc",
72 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
73 },
74 {
75 .name = (char *) "lttng-probe-block",
76 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
77 },
78 {
79 .name = (char *) "lttng-probe-btrfs",
80 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
81 },
82 {
83 .name = (char *) "lttng-probe-compaction",
84 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
85 },
86 {
87 .name = (char *) "lttng-probe-ext3",
88 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
89 },
90 {
91 .name = (char *) "lttng-probe-ext4",
92 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
93 },
94 {
95 .name = (char *) "lttng-probe-gpio",
96 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
97 },
98 {
99 .name = (char *) "lttng-probe-i2c",
100 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
101 },
102 {
103 .name = (char *) "lttng-probe-irq",
104 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
105 },
106 {
107 .name = (char *) "lttng-probe-jbd",
108 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
109 },
110 {
111 .name = (char *) "lttng-probe-jbd2",
112 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
113 },
114 {
115 .name = (char *) "lttng-probe-kmem",
116 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
117 },
118 {
119 .name = (char *) "lttng-probe-kvm",
120 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
121 },
122 {
123 .name = (char *) "lttng-probe-kvm-x86",
124 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
125 },
126 {
127 .name = (char *) "lttng-probe-kvm-x86-mmu",
128 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
129 },
130 {
131 .name = (char *) "lttng-probe-lock",
132 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
133 },
134 {
135 .name = (char *) "lttng-probe-module",
136 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
137 },
138 {
139 .name = (char *) "lttng-probe-napi",
140 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
141 },
142 {
143 .name = (char *) "lttng-probe-net",
144 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
145 },
146 {
147 .name = (char *) "lttng-probe-power",
148 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
149 },
150 {
151 .name = (char *) "lttng-probe-preemptirq",
152 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
153 },
154 {
155 .name = (char *) "lttng-probe-printk",
156 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
157 },
158 {
159 .name = (char *) "lttng-probe-random",
160 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
161 },
162 {
163 .name = (char *) "lttng-probe-rcu",
164 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
165 },
166 {
167 .name = (char *) "lttng-probe-regmap",
168 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
169 },
170 {
171 .name = (char *) "lttng-probe-regulator",
172 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
173 },
174 {
175 .name = (char *) "lttng-probe-rpm",
176 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
177 },
178 {
179 .name = (char *) "lttng-probe-sched",
180 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
181 },
182 {
183 .name = (char *) "lttng-probe-scsi",
184 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
185 },
186 {
187 .name = (char *) "lttng-probe-signal",
188 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
189 },
190 {
191 .name = (char *) "lttng-probe-skb",
192 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
193 },
194 {
195 .name = (char *) "lttng-probe-sock",
196 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
197 },
198 {
199 .name = (char *) "lttng-probe-statedump",
200 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
201 },
202 {
203 .name = (char *) "lttng-probe-sunrpc",
204 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
205 },
206 {
207 .name = (char *) "lttng-probe-timer",
208 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
209 },
210 {
211 .name = (char *) "lttng-probe-udp",
212 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
213 },
214 {
215 .name = (char *) "lttng-probe-vmscan",
216 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
217 },
218 {
219 .name = (char *) "lttng-probe-v4l2",
220 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
221 },
222 {
223 .name = (char *) "lttng-probe-workqueue",
224 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
225 },
226 {
227 .name = (char *) "lttng-probe-writeback",
228 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
229 },
230 {
231 .name = (char *) "lttng-probe-x86-irq-vectors",
232 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
233 },
234 {
235 .name = (char *) "lttng-probe-x86-exceptions",
236 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
237 },
096102bd
DG
238};
239
fbb9748b
JG
240/* dynamic probe modules list */
241static struct kern_modules_param *probes;
242static int nr_probes;
c9d42407 243static int probes_capacity;
fbb9748b 244
ce7fc42f 245#ifdef HAVE_KMOD
234170ac 246#include <libkmod.h>
866c17ce 247
d11b2027
MJ
248/**
249 * @brief Logging function for libkmod integration.
250 */
d22ad5f8 251static ATTR_FORMAT_PRINTF(6, 0)
f46376a1
MJ
252void log_kmod(void *data __attribute__((unused)),
253 int priority __attribute__((unused)),
254 const char *file __attribute__((unused)),
255 int line __attribute__((unused)),
256 const char *fn __attribute__((unused)),
257 const char *format, va_list args)
234170ac
UTL
258{
259 char *str;
260
261 if (vasprintf(&str, format, args) < 0) {
262 return;
263 }
264
265 DBG("libkmod: %s", str);
266 free(str);
267}
866c17ce 268
d11b2027
MJ
269/**
270 * @brief Setup the libkmod context.
271 *
272 * Create the context, add a custom logging function and preload the
273 * ressources for faster operation.
274 *
275 * @returns \c 0 on success
276 * \c < 0 on error
277 */
866c17ce 278static int setup_kmod_ctx(struct kmod_ctx **ctx)
234170ac 279{
866c17ce 280 int ret = 0;
234170ac 281
866c17ce 282 *ctx = kmod_new(NULL, NULL);
234170ac
UTL
283 if (!ctx) {
284 PERROR("Unable to create kmod library context");
285 ret = -ENOMEM;
286 goto error;
287 }
288
d22ad5f8
SM
289 /*
290 * Parameter 2 of kmod_set_log_fn generates a
291 * -Wsuggest-attribute=formatkmod_set_log_fn warning that we can't fix,
292 * ignore it.
293 */
294 DIAGNOSTIC_PUSH
295 DIAGNOSTIC_IGNORE_SUGGEST_ATTRIBUTE_FORMAT
866c17ce 296 kmod_set_log_fn(*ctx, log_kmod, NULL);
d22ad5f8 297 DIAGNOSTIC_POP
866c17ce
MJ
298 ret = kmod_load_resources(*ctx);
299 if (ret < 0) {
300 ERR("Failed to load kmod library resources");
301 goto error;
302 }
303
304error:
305 return ret;
306}
307
d11b2027
MJ
308/**
309 * @brief Loads the kernel modules in \p modules
310 *
311 * @param modules List of modules to load
312 * @param entries Number of modules in the list
d11b2027
MJ
313 *
314 * If the modules are required, we will return with error after the
315 * first failed module load, otherwise we continue loading.
316 *
317 * @returns \c 0 on success
318 * \c < 0 on error
319 */
866c17ce 320static int modprobe_lttng(struct kern_modules_param *modules,
adfe4f5e 321 int entries)
866c17ce
MJ
322{
323 int ret = 0, i;
324 struct kmod_ctx *ctx;
325
326 ret = setup_kmod_ctx(&ctx);
327 if (ret < 0) {
328 goto error;
329 }
234170ac
UTL
330
331 for (i = 0; i < entries; i++) {
332 struct kmod_module *mod = NULL;
333
334 ret = kmod_module_new_from_name(ctx, modules[i].name, &mod);
335 if (ret < 0) {
336 PERROR("Failed to create kmod module for %s", modules[i].name);
337 goto error;
338 }
339
0b1e16b8 340 ret = kmod_module_probe_insert_module(mod, 0,
234170ac 341 NULL, NULL, NULL, NULL);
0b1e16b8
MJ
342 if (ret == -EEXIST) {
343 DBG("Module %s is already loaded", modules[i].name);
344 ret = 0;
345 } else if (ret < 0) {
adfe4f5e 346 if (modules[i].load_policy == KERNEL_MODULE_PROPERTY_LOAD_POLICY_REQUIRED) {
16c2e854
PP
347 ERR("Unable to load required module %s",
348 modules[i].name);
349 goto error;
350 } else {
351 DBG("Unable to load optional module %s; continuing",
352 modules[i].name);
353 ret = 0;
354 }
234170ac
UTL
355 } else {
356 DBG("Modprobe successfully %s", modules[i].name);
4ad664a0 357 modules[i].loaded = true;
234170ac
UTL
358 }
359
360 kmod_module_unref(mod);
361 }
362
363error:
364 if (ctx) {
365 kmod_unref(ctx);
366 }
367 return ret;
368}
369
d11b2027
MJ
370/**
371 * @brief Recursively unload modules.
372 *
373 * This function implements the same modules unloading behavior as
374 * 'modprobe -r' or rmmod, it will recursevily go trought the \p module
375 * dependencies and unload modules with a refcount of 0.
376 *
377 * @param mod The module to unload
378 *
379 * @returns \c 0 on success
380 * \c < 0 on error
381 */
866c17ce
MJ
382static int rmmod_recurse(struct kmod_module *mod) {
383 int ret = 0;
384 struct kmod_list *deps, *itr;
385
386 if (kmod_module_get_initstate(mod) == KMOD_MODULE_BUILTIN) {
387 DBG("Module %s is builtin", kmod_module_get_name(mod));
388 return ret;
389 }
390
391 ret = kmod_module_remove_module(mod, 0);
392
393 deps = kmod_module_get_dependencies(mod);
394 if (deps != NULL) {
395 kmod_list_foreach(itr, deps) {
396 struct kmod_module *dep = kmod_module_get_module(itr);
397 if (kmod_module_get_refcnt(dep) == 0) {
398 DBG("Recursive remove module %s",
399 kmod_module_get_name(dep));
400 rmmod_recurse(dep);
401 }
402 kmod_module_unref(dep);
403 }
404 kmod_module_unref_list(deps);
405 }
406
407 return ret;
408}
409
d11b2027
MJ
410/**
411 * @brief Unloads the kernel modules in \p modules
412 *
413 * @param modules List of modules to unload
414 * @param entries Number of modules in the list
d11b2027
MJ
415 *
416 */
866c17ce 417static void modprobe_remove_lttng(const struct kern_modules_param *modules,
adfe4f5e 418 int entries)
866c17ce
MJ
419{
420 int ret = 0, i;
421 struct kmod_ctx *ctx;
422
423 ret = setup_kmod_ctx(&ctx);
424 if (ret < 0) {
425 goto error;
426 }
427
428 for (i = entries - 1; i >= 0; i--) {
429 struct kmod_module *mod = NULL;
430
4ad664a0
JG
431 if (!modules[i].loaded) {
432 continue;
433 }
434
866c17ce
MJ
435 ret = kmod_module_new_from_name(ctx, modules[i].name, &mod);
436 if (ret < 0) {
437 PERROR("Failed to create kmod module for %s", modules[i].name);
438 goto error;
439 }
440
441 ret = rmmod_recurse(mod);
442 if (ret == -EEXIST) {
443 DBG("Module %s is not in kernel.", modules[i].name);
adfe4f5e 444 } else if (modules[i].load_policy == KERNEL_MODULE_PROPERTY_LOAD_POLICY_REQUIRED && ret < 0) {
866c17ce
MJ
445 ERR("Unable to remove module %s", modules[i].name);
446 } else {
447 DBG("Modprobe removal successful %s",
448 modules[i].name);
449 }
450
451 kmod_module_unref(mod);
452 }
453
454error:
455 if (ctx) {
456 kmod_unref(ctx);
457 }
458}
459
234170ac
UTL
460#else /* HAVE_KMOD */
461
fbb9748b 462static int modprobe_lttng(struct kern_modules_param *modules,
adfe4f5e 463 int entries)
096102bd
DG
464{
465 int ret = 0, i;
466 char modprobe[256];
467
e23b81ed 468 for (i = 0; i < entries; i++) {
096102bd
DG
469 ret = snprintf(modprobe, sizeof(modprobe),
470 "/sbin/modprobe %s%s",
adfe4f5e 471 modules[i].load_policy == KERNEL_MODULE_PROPERTY_LOAD_POLICY_REQUIRED ? "" : "-q ",
e23b81ed 472 modules[i].name);
096102bd
DG
473 if (ret < 0) {
474 PERROR("snprintf modprobe");
475 goto error;
476 }
477 modprobe[sizeof(modprobe) - 1] = '\0';
478 ret = system(modprobe);
479 if (ret == -1) {
adfe4f5e 480 if (modules[i].load_policy == KERNEL_MODULE_PROPERTY_LOAD_POLICY_REQUIRED) {
16c2e854
PP
481 ERR("Unable to launch modprobe for required module %s",
482 modules[i].name);
483 goto error;
484 } else {
485 DBG("Unable to launch modprobe for optional module %s; continuing",
486 modules[i].name);
487 ret = 0;
488 }
489 } else if (WEXITSTATUS(ret) != 0) {
adfe4f5e 490 if (modules[i].load_policy == KERNEL_MODULE_PROPERTY_LOAD_POLICY_REQUIRED) {
16c2e854
PP
491 ERR("Unable to load required module %s",
492 modules[i].name);
493 goto error;
494 } else {
495 DBG("Unable to load optional module %s; continuing",
496 modules[i].name);
497 ret = 0;
498 }
096102bd 499 } else {
ab57d7d3 500 DBG("Modprobe successfully %s", modules[i].name);
355d2778 501 modules[i].loaded = true;
096102bd
DG
502 }
503 }
504
505error:
506 return ret;
507}
508
35e090b7 509static void modprobe_remove_lttng(const struct kern_modules_param *modules,
adfe4f5e 510 int entries)
35e090b7
MJ
511{
512 int ret = 0, i;
513 char modprobe[256];
514
515 for (i = entries - 1; i >= 0; i--) {
4ad664a0
JG
516 if (!modules[i].loaded) {
517 continue;
518 }
35e090b7
MJ
519 ret = snprintf(modprobe, sizeof(modprobe),
520 "/sbin/modprobe -r -q %s",
521 modules[i].name);
522 if (ret < 0) {
523 PERROR("snprintf modprobe -r");
524 return;
525 }
526 modprobe[sizeof(modprobe) - 1] = '\0';
527 ret = system(modprobe);
528 if (ret == -1) {
1d25334c
FD
529 if (modules[i].load_policy == KERNEL_MODULE_PROPERTY_LOAD_POLICY_REQUIRED) {
530 ERR("Unable to launch modprobe -r for required module %s",
531 modules[i].name);
532 } else {
533 DBG("Unable to launch modprobe -r for optional module %s",
534 modules[i].name);
535 }
536 } else if (WEXITSTATUS(ret) != 0) {
537 if (modules[i].load_policy == KERNEL_MODULE_PROPERTY_LOAD_POLICY_REQUIRED) {
538 ERR("Unable to remove required module %s",
539 modules[i].name);
540 } else {
541 DBG("Unable to remove optional module %s",
542 modules[i].name);
543 }
35e090b7 544 } else {
1d25334c 545 DBG("Modprobe removal successful %s", modules[i].name);
35e090b7
MJ
546 }
547 }
548}
549
866c17ce
MJ
550#endif /* HAVE_KMOD */
551
35e090b7
MJ
552/*
553 * Remove control kernel module(s) in reverse load order.
554 */
555void modprobe_remove_lttng_control(void)
556{
557 modprobe_remove_lttng(kern_modules_control_core,
adfe4f5e 558 ARRAY_SIZE(kern_modules_control_core));
35e090b7
MJ
559}
560
561static void free_probes(void)
562{
563 int i;
564
565 if (!probes) {
566 return;
567 }
568 for (i = 0; i < nr_probes; ++i) {
569 free(probes[i].name);
570 }
571 free(probes);
572 probes = NULL;
573 nr_probes = 0;
574}
575
576/*
577 * Remove data kernel modules in reverse load order.
578 */
579void modprobe_remove_lttng_data(void)
580{
581 if (!probes) {
582 return;
583 }
adfe4f5e
JG
584
585 modprobe_remove_lttng(probes, nr_probes);
35e090b7
MJ
586 free_probes();
587}
588
589/*
590 * Remove all kernel modules in reverse order.
591 */
592void modprobe_remove_lttng_all(void)
593{
594 modprobe_remove_lttng_data();
595 modprobe_remove_lttng_control();
596}
597
e23b81ed
JG
598/*
599 * Load control kernel module(s).
600 */
601int modprobe_lttng_control(void)
602{
adfe4f5e
JG
603 return modprobe_lttng(kern_modules_control_core,
604 ARRAY_SIZE(kern_modules_control_core));
e23b81ed 605}
ab57d7d3 606
c9d42407
PP
607/**
608 * Grow global list of probes (double capacity or set it to 1 if
609 * currently 0 and copy existing data).
096102bd 610 */
c9d42407 611static int grow_probes(void)
096102bd 612{
c9d42407
PP
613 int i;
614 struct kern_modules_param *tmp_probes;
fbb9748b 615
c9d42407
PP
616 /* Initialize capacity to 1 if 0. */
617 if (probes_capacity == 0) {
7966af57 618 probes = (kern_modules_param *) zmalloc(sizeof(*probes));
c9d42407
PP
619 if (!probes) {
620 PERROR("malloc probe list");
621 return -ENOMEM;
622 }
623
624 probes_capacity = 1;
625 return 0;
fbb9748b
JG
626 }
627
c9d42407
PP
628 /* Double size. */
629 probes_capacity *= 2;
630
7966af57 631 tmp_probes = (kern_modules_param *) zmalloc(sizeof(*tmp_probes) * probes_capacity);
c9d42407 632 if (!tmp_probes) {
fbb9748b
JG
633 PERROR("malloc probe list");
634 return -ENOMEM;
635 }
636
c9d42407 637 for (i = 0; i < nr_probes; ++i) {
adfe4f5e
JG
638 /* Ownership of 'name' field is transferred. */
639 tmp_probes[i] = probes[i];
c9d42407
PP
640 }
641
642 /* Replace probes with larger copy. */
643 free(probes);
644 probes = tmp_probes;
645
646 return 0;
647}
648
649/*
650 * Appends a comma-separated list of probes to the global list
651 * of probes.
652 */
653static int append_list_to_probes(const char *list)
654{
655 char *next;
d3c04b7c 656 int ret;
50e0fa5f 657 char *tmp_list, *cur_list, *saveptr;
c9d42407 658
a0377dfe 659 LTTNG_ASSERT(list);
c9d42407 660
44603c80 661 cur_list = tmp_list = strdup(list);
c9d42407
PP
662 if (!tmp_list) {
663 PERROR("strdup temp list");
664 return -ENOMEM;
665 }
666
667 for (;;) {
fbb9748b 668 size_t name_len;
c9d42407 669 struct kern_modules_param *cur_mod;
fbb9748b 670
50e0fa5f 671 next = strtok_r(cur_list, ",", &saveptr);
fbb9748b 672 if (!next) {
c9d42407 673 break;
fbb9748b 674 }
44603c80 675 cur_list = NULL;
fbb9748b
JG
676
677 /* filter leading spaces */
678 while (*next == ' ') {
679 next++;
680 }
681
c9d42407
PP
682 if (probes_capacity <= nr_probes) {
683 ret = grow_probes();
684 if (ret) {
398d5459 685 goto error;
c9d42407
PP
686 }
687 }
688
fbb9748b
JG
689 /* Length 13 is "lttng-probe-" + \0 */
690 name_len = strlen(next) + 13;
691
d3c04b7c 692 cur_mod = &probes[nr_probes];
7966af57 693 cur_mod->name = (char *) zmalloc(name_len);
c9d42407 694 if (!cur_mod->name) {
fbb9748b 695 PERROR("malloc probe list");
398d5459
MD
696 ret = -ENOMEM;
697 goto error;
fbb9748b
JG
698 }
699
c9d42407 700 ret = snprintf(cur_mod->name, name_len, "lttng-probe-%s", next);
fbb9748b
JG
701 if (ret < 0) {
702 PERROR("snprintf modprobe name");
398d5459
MD
703 ret = -ENOMEM;
704 goto error;
fbb9748b 705 }
c9d42407 706
adfe4f5e
JG
707 cur_mod->load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL;
708
c9d42407 709 nr_probes++;
fbb9748b
JG
710 }
711
c9d42407 712 free(tmp_list);
c9d42407 713 return 0;
398d5459
MD
714
715error:
716 free(tmp_list);
717 free_probes();
718 return ret;
c9d42407
PP
719}
720
721/*
722 * Load data kernel module(s).
723 */
724int modprobe_lttng_data(void)
725{
726 int ret, i;
727 char *list;
728
729 /*
730 * Base probes: either from command line option, environment
731 * variable or default list.
732 */
412d7227 733 list = the_config.kmod_probes_list.value;
c9d42407
PP
734 if (list) {
735 /* User-specified probes. */
736 ret = append_list_to_probes(list);
c9d42407
PP
737 if (ret) {
738 return ret;
739 }
740 } else {
741 /* Default probes. */
742 int def_len = ARRAY_SIZE(kern_modules_probes_default);
c9d42407 743
7966af57 744 probes = (kern_modules_param *) zmalloc(sizeof(*probes) * def_len);
c9d42407
PP
745 if (!probes) {
746 PERROR("malloc probe list");
747 return -ENOMEM;
748 }
749
750 nr_probes = probes_capacity = def_len;
751
752 for (i = 0; i < def_len; ++i) {
753 char* name = strdup(kern_modules_probes_default[i].name);
754
755 if (!name) {
756 PERROR("strdup probe item");
398d5459
MD
757 ret = -ENOMEM;
758 goto error;
c9d42407
PP
759 }
760
761 probes[i].name = name;
adfe4f5e 762 probes[i].load_policy = kern_modules_probes_default[i].load_policy;
c9d42407
PP
763 }
764 }
765
766 /*
767 * Extra modules? Append them to current probes list.
768 */
412d7227 769 list = the_config.kmod_extra_probes_list.value;
c9d42407
PP
770 if (list) {
771 ret = append_list_to_probes(list);
772 if (ret) {
398d5459 773 goto error;
c9d42407
PP
774 }
775 }
776
777 /*
778 * Load probes modules now.
779 */
adfe4f5e 780 ret = modprobe_lttng(probes, nr_probes);
398d5459
MD
781 if (ret) {
782 goto error;
783 }
784 return ret;
785
786error:
787 free_probes();
788 return ret;
096102bd 789}
This page took 0.102134 seconds and 4 git commands to generate.