Typo: occurences -> occurrences
[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 <stdio.h>
18 #include <stdlib.h>
19 #include <sys/wait.h>
20
21 #include <common/common.h>
22 #include <common/utils.h>
23
24 #include "modprobe.h"
25 #include "kern-modules.h"
26 #include "lttng-sessiond.h"
27
28 /* LTTng kernel tracer mandatory core modules list */
29 struct kern_modules_param kern_modules_control_core[] = {
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 },
54 {
55 .name = (char *) "lttng-ring-buffer-event_notifier-client",
56 .load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL,
57 },
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 },
66 };
67
68 /* LTTng kerneltracer probe modules list */
69 struct kern_modules_param kern_modules_probes_default[] = {
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 },
238 };
239
240 /* dynamic probe modules list */
241 static struct kern_modules_param *probes;
242 static int nr_probes;
243 static int probes_capacity;
244
245 #if HAVE_KMOD
246 #include <libkmod.h>
247
248 /**
249 * @brief Logging function for libkmod integration.
250 */
251 static void log_kmod(void *data, int priority, const char *file, int line,
252 const char *fn, const char *format, va_list args)
253 {
254 char *str;
255
256 if (vasprintf(&str, format, args) < 0) {
257 return;
258 }
259
260 DBG("libkmod: %s", str);
261 free(str);
262 }
263
264 /**
265 * @brief Setup the libkmod context.
266 *
267 * Create the context, add a custom logging function and preload the
268 * ressources for faster operation.
269 *
270 * @returns \c 0 on success
271 * \c < 0 on error
272 */
273 static int setup_kmod_ctx(struct kmod_ctx **ctx)
274 {
275 int ret = 0;
276
277 *ctx = kmod_new(NULL, NULL);
278 if (!ctx) {
279 PERROR("Unable to create kmod library context");
280 ret = -ENOMEM;
281 goto error;
282 }
283
284 kmod_set_log_fn(*ctx, log_kmod, NULL);
285 ret = kmod_load_resources(*ctx);
286 if (ret < 0) {
287 ERR("Failed to load kmod library resources");
288 goto error;
289 }
290
291 error:
292 return ret;
293 }
294
295 /**
296 * @brief Loads the kernel modules in \p modules
297 *
298 * @param modules List of modules to load
299 * @param entries Number of modules in the list
300 *
301 * If the modules are required, we will return with error after the
302 * first failed module load, otherwise we continue loading.
303 *
304 * @returns \c 0 on success
305 * \c < 0 on error
306 */
307 static int modprobe_lttng(struct kern_modules_param *modules,
308 int entries)
309 {
310 int ret = 0, i;
311 struct kmod_ctx *ctx;
312
313 ret = setup_kmod_ctx(&ctx);
314 if (ret < 0) {
315 goto error;
316 }
317
318 for (i = 0; i < entries; i++) {
319 struct kmod_module *mod = NULL;
320
321 ret = kmod_module_new_from_name(ctx, modules[i].name, &mod);
322 if (ret < 0) {
323 PERROR("Failed to create kmod module for %s", modules[i].name);
324 goto error;
325 }
326
327 ret = kmod_module_probe_insert_module(mod, 0,
328 NULL, NULL, NULL, NULL);
329 if (ret == -EEXIST) {
330 DBG("Module %s is already loaded", modules[i].name);
331 ret = 0;
332 } else if (ret < 0) {
333 if (modules[i].load_policy == KERNEL_MODULE_PROPERTY_LOAD_POLICY_REQUIRED) {
334 ERR("Unable to load required module %s",
335 modules[i].name);
336 goto error;
337 } else {
338 DBG("Unable to load optional module %s; continuing",
339 modules[i].name);
340 ret = 0;
341 }
342 } else {
343 DBG("Modprobe successfully %s", modules[i].name);
344 modules[i].loaded = true;
345 }
346
347 kmod_module_unref(mod);
348 }
349
350 error:
351 if (ctx) {
352 kmod_unref(ctx);
353 }
354 return ret;
355 }
356
357 /**
358 * @brief Recursively unload modules.
359 *
360 * This function implements the same modules unloading behavior as
361 * 'modprobe -r' or rmmod, it will recursevily go trought the \p module
362 * dependencies and unload modules with a refcount of 0.
363 *
364 * @param mod The module to unload
365 *
366 * @returns \c 0 on success
367 * \c < 0 on error
368 */
369 static int rmmod_recurse(struct kmod_module *mod) {
370 int ret = 0;
371 struct kmod_list *deps, *itr;
372
373 if (kmod_module_get_initstate(mod) == KMOD_MODULE_BUILTIN) {
374 DBG("Module %s is builtin", kmod_module_get_name(mod));
375 return ret;
376 }
377
378 ret = kmod_module_remove_module(mod, 0);
379
380 deps = kmod_module_get_dependencies(mod);
381 if (deps != NULL) {
382 kmod_list_foreach(itr, deps) {
383 struct kmod_module *dep = kmod_module_get_module(itr);
384 if (kmod_module_get_refcnt(dep) == 0) {
385 DBG("Recursive remove module %s",
386 kmod_module_get_name(dep));
387 rmmod_recurse(dep);
388 }
389 kmod_module_unref(dep);
390 }
391 kmod_module_unref_list(deps);
392 }
393
394 return ret;
395 }
396
397 /**
398 * @brief Unloads the kernel modules in \p modules
399 *
400 * @param modules List of modules to unload
401 * @param entries Number of modules in the list
402 *
403 */
404 static void modprobe_remove_lttng(const struct kern_modules_param *modules,
405 int entries)
406 {
407 int ret = 0, i;
408 struct kmod_ctx *ctx;
409
410 ret = setup_kmod_ctx(&ctx);
411 if (ret < 0) {
412 goto error;
413 }
414
415 for (i = entries - 1; i >= 0; i--) {
416 struct kmod_module *mod = NULL;
417
418 if (!modules[i].loaded) {
419 continue;
420 }
421
422 ret = kmod_module_new_from_name(ctx, modules[i].name, &mod);
423 if (ret < 0) {
424 PERROR("Failed to create kmod module for %s", modules[i].name);
425 goto error;
426 }
427
428 ret = rmmod_recurse(mod);
429 if (ret == -EEXIST) {
430 DBG("Module %s is not in kernel.", modules[i].name);
431 } else if (modules[i].load_policy == KERNEL_MODULE_PROPERTY_LOAD_POLICY_REQUIRED && ret < 0) {
432 ERR("Unable to remove module %s", modules[i].name);
433 } else {
434 DBG("Modprobe removal successful %s",
435 modules[i].name);
436 }
437
438 kmod_module_unref(mod);
439 }
440
441 error:
442 if (ctx) {
443 kmod_unref(ctx);
444 }
445 }
446
447 #else /* HAVE_KMOD */
448
449 static int modprobe_lttng(struct kern_modules_param *modules,
450 int entries)
451 {
452 int ret = 0, i;
453 char modprobe[256];
454
455 for (i = 0; i < entries; i++) {
456 ret = snprintf(modprobe, sizeof(modprobe),
457 "/sbin/modprobe %s%s",
458 modules[i].load_policy == KERNEL_MODULE_PROPERTY_LOAD_POLICY_REQUIRED ? "" : "-q ",
459 modules[i].name);
460 if (ret < 0) {
461 PERROR("snprintf modprobe");
462 goto error;
463 }
464 modprobe[sizeof(modprobe) - 1] = '\0';
465 ret = system(modprobe);
466 if (ret == -1) {
467 if (modules[i].load_policy == KERNEL_MODULE_PROPERTY_LOAD_POLICY_REQUIRED) {
468 ERR("Unable to launch modprobe for required module %s",
469 modules[i].name);
470 goto error;
471 } else {
472 DBG("Unable to launch modprobe for optional module %s; continuing",
473 modules[i].name);
474 ret = 0;
475 }
476 } else if (WEXITSTATUS(ret) != 0) {
477 if (modules[i].load_policy == KERNEL_MODULE_PROPERTY_LOAD_POLICY_REQUIRED) {
478 ERR("Unable to load required module %s",
479 modules[i].name);
480 goto error;
481 } else {
482 DBG("Unable to load optional module %s; continuing",
483 modules[i].name);
484 ret = 0;
485 }
486 } else {
487 DBG("Modprobe successfully %s", modules[i].name);
488 modules[i].loaded = true;
489 }
490 }
491
492 error:
493 return ret;
494 }
495
496 static void modprobe_remove_lttng(const struct kern_modules_param *modules,
497 int entries)
498 {
499 int ret = 0, i;
500 char modprobe[256];
501
502 for (i = entries - 1; i >= 0; i--) {
503 if (!modules[i].loaded) {
504 continue;
505 }
506 ret = snprintf(modprobe, sizeof(modprobe),
507 "/sbin/modprobe -r -q %s",
508 modules[i].name);
509 if (ret < 0) {
510 PERROR("snprintf modprobe -r");
511 return;
512 }
513 modprobe[sizeof(modprobe) - 1] = '\0';
514 ret = system(modprobe);
515 if (ret == -1) {
516 if (modules[i].load_policy == KERNEL_MODULE_PROPERTY_LOAD_POLICY_REQUIRED) {
517 ERR("Unable to launch modprobe -r for required module %s",
518 modules[i].name);
519 } else {
520 DBG("Unable to launch modprobe -r for optional module %s",
521 modules[i].name);
522 }
523 } else if (WEXITSTATUS(ret) != 0) {
524 if (modules[i].load_policy == KERNEL_MODULE_PROPERTY_LOAD_POLICY_REQUIRED) {
525 ERR("Unable to remove required module %s",
526 modules[i].name);
527 } else {
528 DBG("Unable to remove optional module %s",
529 modules[i].name);
530 }
531 } else {
532 DBG("Modprobe removal successful %s", modules[i].name);
533 }
534 }
535 }
536
537 #endif /* HAVE_KMOD */
538
539 /*
540 * Remove control kernel module(s) in reverse load order.
541 */
542 void modprobe_remove_lttng_control(void)
543 {
544 modprobe_remove_lttng(kern_modules_control_core,
545 ARRAY_SIZE(kern_modules_control_core));
546 }
547
548 static void free_probes(void)
549 {
550 int i;
551
552 if (!probes) {
553 return;
554 }
555 for (i = 0; i < nr_probes; ++i) {
556 free(probes[i].name);
557 }
558 free(probes);
559 probes = NULL;
560 nr_probes = 0;
561 }
562
563 /*
564 * Remove data kernel modules in reverse load order.
565 */
566 void modprobe_remove_lttng_data(void)
567 {
568 if (!probes) {
569 return;
570 }
571
572 modprobe_remove_lttng(probes, nr_probes);
573 free_probes();
574 }
575
576 /*
577 * Remove all kernel modules in reverse order.
578 */
579 void modprobe_remove_lttng_all(void)
580 {
581 modprobe_remove_lttng_data();
582 modprobe_remove_lttng_control();
583 }
584
585 /*
586 * Load control kernel module(s).
587 */
588 int modprobe_lttng_control(void)
589 {
590 return modprobe_lttng(kern_modules_control_core,
591 ARRAY_SIZE(kern_modules_control_core));
592 }
593
594 /**
595 * Grow global list of probes (double capacity or set it to 1 if
596 * currently 0 and copy existing data).
597 */
598 static int grow_probes(void)
599 {
600 int i;
601 struct kern_modules_param *tmp_probes;
602
603 /* Initialize capacity to 1 if 0. */
604 if (probes_capacity == 0) {
605 probes = zmalloc(sizeof(*probes));
606 if (!probes) {
607 PERROR("malloc probe list");
608 return -ENOMEM;
609 }
610
611 probes_capacity = 1;
612 return 0;
613 }
614
615 /* Double size. */
616 probes_capacity *= 2;
617
618 tmp_probes = zmalloc(sizeof(*tmp_probes) * probes_capacity);
619 if (!tmp_probes) {
620 PERROR("malloc probe list");
621 return -ENOMEM;
622 }
623
624 for (i = 0; i < nr_probes; ++i) {
625 /* Ownership of 'name' field is transferred. */
626 tmp_probes[i] = probes[i];
627 }
628
629 /* Replace probes with larger copy. */
630 free(probes);
631 probes = tmp_probes;
632
633 return 0;
634 }
635
636 /*
637 * Appends a comma-separated list of probes to the global list
638 * of probes.
639 */
640 static int append_list_to_probes(const char *list)
641 {
642 char *next;
643 int ret;
644 char *tmp_list, *cur_list, *saveptr;
645
646 LTTNG_ASSERT(list);
647
648 cur_list = tmp_list = strdup(list);
649 if (!tmp_list) {
650 PERROR("strdup temp list");
651 return -ENOMEM;
652 }
653
654 for (;;) {
655 size_t name_len;
656 struct kern_modules_param *cur_mod;
657
658 next = strtok_r(cur_list, ",", &saveptr);
659 if (!next) {
660 break;
661 }
662 cur_list = NULL;
663
664 /* filter leading spaces */
665 while (*next == ' ') {
666 next++;
667 }
668
669 if (probes_capacity <= nr_probes) {
670 ret = grow_probes();
671 if (ret) {
672 goto error;
673 }
674 }
675
676 /* Length 13 is "lttng-probe-" + \0 */
677 name_len = strlen(next) + 13;
678
679 cur_mod = &probes[nr_probes];
680 cur_mod->name = zmalloc(name_len);
681 if (!cur_mod->name) {
682 PERROR("malloc probe list");
683 ret = -ENOMEM;
684 goto error;
685 }
686
687 ret = snprintf(cur_mod->name, name_len, "lttng-probe-%s", next);
688 if (ret < 0) {
689 PERROR("snprintf modprobe name");
690 ret = -ENOMEM;
691 goto error;
692 }
693
694 cur_mod->load_policy = KERNEL_MODULE_PROPERTY_LOAD_POLICY_OPTIONAL;
695
696 nr_probes++;
697 }
698
699 free(tmp_list);
700 return 0;
701
702 error:
703 free(tmp_list);
704 free_probes();
705 return ret;
706 }
707
708 /*
709 * Load data kernel module(s).
710 */
711 int modprobe_lttng_data(void)
712 {
713 int ret, i;
714 char *list;
715
716 /*
717 * Base probes: either from command line option, environment
718 * variable or default list.
719 */
720 list = the_config.kmod_probes_list.value;
721 if (list) {
722 /* User-specified probes. */
723 ret = append_list_to_probes(list);
724 if (ret) {
725 return ret;
726 }
727 } else {
728 /* Default probes. */
729 int def_len = ARRAY_SIZE(kern_modules_probes_default);
730
731 probes = zmalloc(sizeof(*probes) * def_len);
732 if (!probes) {
733 PERROR("malloc probe list");
734 return -ENOMEM;
735 }
736
737 nr_probes = probes_capacity = def_len;
738
739 for (i = 0; i < def_len; ++i) {
740 char* name = strdup(kern_modules_probes_default[i].name);
741
742 if (!name) {
743 PERROR("strdup probe item");
744 ret = -ENOMEM;
745 goto error;
746 }
747
748 probes[i].name = name;
749 probes[i].load_policy = kern_modules_probes_default[i].load_policy;
750 }
751 }
752
753 /*
754 * Extra modules? Append them to current probes list.
755 */
756 list = the_config.kmod_extra_probes_list.value;
757 if (list) {
758 ret = append_list_to_probes(list);
759 if (ret) {
760 goto error;
761 }
762 }
763
764 /*
765 * Load probes modules now.
766 */
767 ret = modprobe_lttng(probes, nr_probes);
768 if (ret) {
769 goto error;
770 }
771 return ret;
772
773 error:
774 free_probes();
775 return ret;
776 }
This page took 0.048067 seconds and 4 git commands to generate.