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