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