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