SoW-2019-0002: Dynamic Snapshot
[lttng-tools.git] / src / bin / lttng-sessiond / modprobe.c
1 /*
2 * Copyright (C) 2011 David Goulet <dgoulet@efficios.com>
3 * Copyright (C) 2014 Jan Glauber <jan.glauber@gmail.com>
4 *
5 * SPDX-License-Identifier: GPL-2.0-only
6 *
7 */
8
9 /**
10 * @file modprobe.c
11 *
12 * @brief modprobe related functions.
13 *
14 */
15
16 #define _LGPL_SOURCE
17 #include <assert.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <sys/wait.h>
21
22 #include <common/common.h>
23 #include <common/utils.h>
24
25 #include "modprobe.h"
26 #include "kern-modules.h"
27 #include "lttng-sessiond.h"
28
29 #define LTTNG_MOD_REQUIRED 1
30 #define LTTNG_MOD_OPTIONAL 0
31
32 /* LTTng kernel tracer mandatory core modules list */
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 */
37 struct kern_modules_param kern_modules_control_core[] = {
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" },
45 };
46
47 /* LTTng kernel tracer probe modules list */
48 struct kern_modules_param kern_modules_probes_default[] = {
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" },
91 };
92
93 /* dynamic probe modules list */
94 static struct kern_modules_param *probes;
95 static int nr_probes;
96 static int probes_capacity;
97
98 #if HAVE_KMOD
99 #include <libkmod.h>
100
101 /**
102 * @brief Logging function for libkmod integration.
103 */
104 static 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 }
116
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 */
126 static int setup_kmod_ctx(struct kmod_ctx **ctx)
127 {
128 int ret = 0;
129
130 *ctx = kmod_new(NULL, NULL);
131 if (!ctx) {
132 PERROR("Unable to create kmod library context");
133 ret = -ENOMEM;
134 goto error;
135 }
136
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
144 error:
145 return ret;
146 }
147
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 */
161 static 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 }
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
181 ret = kmod_module_probe_insert_module(mod, 0,
182 NULL, NULL, NULL, NULL);
183 if (ret == -EEXIST) {
184 DBG("Module %s is already loaded", modules[i].name);
185 ret = 0;
186 } else if (ret < 0) {
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 }
196 } else {
197 DBG("Modprobe successfully %s", modules[i].name);
198 modules[i].loaded = true;
199 }
200
201 kmod_module_unref(mod);
202 }
203
204 error:
205 if (ctx) {
206 kmod_unref(ctx);
207 }
208 return ret;
209 }
210
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 */
223 static 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
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 */
259 static 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
273 if (!modules[i].loaded) {
274 continue;
275 }
276
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
296 error:
297 if (ctx) {
298 kmod_unref(ctx);
299 }
300 }
301
302 #else /* HAVE_KMOD */
303
304 static int modprobe_lttng(struct kern_modules_param *modules,
305 int entries, int required)
306 {
307 int ret = 0, i;
308 char modprobe[256];
309
310 for (i = 0; i < entries; i++) {
311 ret = snprintf(modprobe, sizeof(modprobe),
312 "/sbin/modprobe %s%s",
313 required ? "" : "-q ",
314 modules[i].name);
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) {
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 }
341 } else {
342 DBG("Modprobe successfully %s", modules[i].name);
343 modules[i].loaded = true;
344 }
345 }
346
347 error:
348 return ret;
349 }
350
351 static 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--) {
358 if (!modules[i].loaded) {
359 continue;
360 }
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
383 #endif /* HAVE_KMOD */
384
385 /*
386 * Remove control kernel module(s) in reverse load order.
387 */
388 void 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
395 static 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 */
413 void 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 */
425 void modprobe_remove_lttng_all(void)
426 {
427 modprobe_remove_lttng_data();
428 modprobe_remove_lttng_control();
429 }
430
431 /*
432 * Load control kernel module(s).
433 */
434 int modprobe_lttng_control(void)
435 {
436 int ret;
437
438 ret = modprobe_lttng(kern_modules_control_core,
439 ARRAY_SIZE(kern_modules_control_core),
440 LTTNG_MOD_REQUIRED);
441 return ret;
442 }
443
444 /**
445 * Grow global list of probes (double capacity or set it to 1 if
446 * currently 0 and copy existing data).
447 */
448 static int grow_probes(void)
449 {
450 int i;
451 struct kern_modules_param *tmp_probes;
452
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;
463 }
464
465 /* Double size. */
466 probes_capacity *= 2;
467
468 tmp_probes = zmalloc(sizeof(*tmp_probes) * probes_capacity);
469 if (!tmp_probes) {
470 PERROR("malloc probe list");
471 return -ENOMEM;
472 }
473
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 */
490 static int append_list_to_probes(const char *list)
491 {
492 char *next;
493 int ret;
494 char *tmp_list, *cur_list;
495
496 assert(list);
497
498 cur_list = tmp_list = strdup(list);
499 if (!tmp_list) {
500 PERROR("strdup temp list");
501 return -ENOMEM;
502 }
503
504 for (;;) {
505 size_t name_len;
506 struct kern_modules_param *cur_mod;
507
508 next = strtok(cur_list, ",");
509 if (!next) {
510 break;
511 }
512 cur_list = NULL;
513
514 /* filter leading spaces */
515 while (*next == ' ') {
516 next++;
517 }
518
519 if (probes_capacity <= nr_probes) {
520 ret = grow_probes();
521 if (ret) {
522 goto error;
523 }
524 }
525
526 /* Length 13 is "lttng-probe-" + \0 */
527 name_len = strlen(next) + 13;
528
529 cur_mod = &probes[nr_probes];
530 cur_mod->name = zmalloc(name_len);
531 if (!cur_mod->name) {
532 PERROR("malloc probe list");
533 ret = -ENOMEM;
534 goto error;
535 }
536
537 ret = snprintf(cur_mod->name, name_len, "lttng-probe-%s", next);
538 if (ret < 0) {
539 PERROR("snprintf modprobe name");
540 ret = -ENOMEM;
541 goto error;
542 }
543
544 nr_probes++;
545 }
546
547 free(tmp_list);
548 return 0;
549
550 error:
551 free(tmp_list);
552 free_probes();
553 return ret;
554 }
555
556 /*
557 * Load data kernel module(s).
558 */
559 int 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 */
568 list = config.kmod_probes_list.value;
569 if (list) {
570 /* User-specified probes. */
571 ret = append_list_to_probes(list);
572 if (ret) {
573 return ret;
574 }
575 } else {
576 /* Default probes. */
577 int def_len = ARRAY_SIZE(kern_modules_probes_default);
578
579 probes = zmalloc(sizeof(*probes) * def_len);
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");
592 ret = -ENOMEM;
593 goto error;
594 }
595
596 probes[i].name = name;
597 }
598 }
599
600 /*
601 * Extra modules? Append them to current probes list.
602 */
603 list = config.kmod_extra_probes_list.value;
604 if (list) {
605 ret = append_list_to_probes(list);
606 if (ret) {
607 goto error;
608 }
609 }
610
611 /*
612 * Load probes modules now.
613 */
614 ret = modprobe_lttng(probes, nr_probes, LTTNG_MOD_OPTIONAL);
615 if (ret) {
616 goto error;
617 }
618 return ret;
619
620 error:
621 free_probes();
622 return ret;
623 }
This page took 0.043857 seconds and 5 git commands to generate.