]> git.ipfire.org Git - thirdparty/kmod.git/blob - tools/depmod.c
Remove ifdef for building tools not bundled
[thirdparty/kmod.git] / tools / depmod.c
1 /*
2 * kmod-depmod - calculate modules.dep using libkmod.
3 *
4 * Copyright (C) 2011-2012 ProFUSION embedded systems
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19 #include "libkmod.h"
20 #include "libkmod-array.h"
21 #include "libkmod-hash.h"
22 #include "libkmod-util.h"
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <getopt.h>
27 #include <errno.h>
28 #include <string.h>
29 #include <syslog.h>
30 #include <limits.h>
31 #include <dirent.h>
32 #include <sys/utsname.h>
33 #include <sys/stat.h>
34 #include <regex.h>
35 #include <assert.h>
36 #include <unistd.h>
37 #include <ctype.h>
38
39 #define DEFAULT_VERBOSE LOG_WARNING
40 static int verbose = DEFAULT_VERBOSE;
41
42 static const struct kmod_ext {
43 const char *ext;
44 size_t len;
45 } kmod_exts[] = {
46 {".ko", sizeof(".ko") - 1},
47 #ifdef ENABLE_ZLIB
48 {".ko.gz", sizeof(".ko.gz") - 1},
49 #endif
50 #ifdef ENABLE_XZ
51 {".ko.xz", sizeof(".ko.xz") - 1},
52 #endif
53 {NULL, 0},
54 };
55
56 static const char CFG_BUILTIN_KEY[] = "built-in";
57 static const char *default_cfg_paths[] = {
58 "/run/depmod.d",
59 SYSCONFDIR "/depmod.d",
60 ROOTPREFIX "/lib/depmod.d",
61 NULL
62 };
63
64 static const char cmdopts_s[] = "aAb:C:E:F:euqrvnP:wmVh";
65 static const struct option cmdopts[] = {
66 {"all", no_argument, 0, 'a'},
67 {"quick", no_argument, 0, 'A'},
68 {"basedir", required_argument, 0, 'b'},
69 {"config", required_argument, 0, 'C'},
70 {"symvers", required_argument, 0, 'E'},
71 {"filesyms", required_argument, 0, 'F'},
72 {"errsyms", no_argument, 0, 'e'},
73 {"unresolved-error", no_argument, 0, 'u'}, /* deprecated */
74 {"quiet", no_argument, 0, 'q'}, /* deprecated */
75 {"root", no_argument, 0, 'r'}, /* deprecated */
76 {"verbose", no_argument, 0, 'v'},
77 {"show", no_argument, 0, 'n'},
78 {"dry-run", no_argument, 0, 'n'},
79 {"symbol-prefix", no_argument, 0, 'P'},
80 {"warn", no_argument, 0, 'w'},
81 {"map", no_argument, 0, 'm'}, /* deprecated */
82 {"version", no_argument, 0, 'V'},
83 {"help", no_argument, 0, 'h'},
84 {NULL, 0, 0, 0}
85 };
86
87 static void help(const char *progname)
88 {
89 fprintf(stderr,
90 "Usage:\n"
91 "\t%s -[aA] [options] [forced_version]\n"
92 "\n"
93 "If no arguments (except options) are given, \"depmod -a\" is assumed\n"
94 "\n"
95 "depmod will output a dependency list suitable for the modprobe utility.\n"
96 "\n"
97 "Options:\n"
98 "\t-a, --all Probe all modules\n"
99 "\t-A, --quick Only does the work if there's a new module\n"
100 "\t-e, --errsyms Report not supplied symbols\n"
101 "\t-n, --show Write the dependency file on stdout only\n"
102 "\t-P, --symbol-prefix Architecture symbol prefix\n"
103 "\t-C, --config=PATH Read configuration from PATH\n"
104 "\t-v, --verbose Enable verbose mode\n"
105 "\t-w, --warn Warn on duplicates\n"
106 "\t-V, --version show version\n"
107 "\t-h, --help show this help\n"
108 "\n"
109 "The following options are useful for people managing distributions:\n"
110 "\t-b, --basedir=DIR Use an image of a module tree.\n"
111 "\t-F, --filesyms=FILE Use the file instead of the\n"
112 "\t current kernel symbols.\n"
113 "\t-E, --symvers=FILE Use Module.symvers file to check\n"
114 "\t symbol versions.\n",
115 progname);
116 }
117
118 static inline void _show(const char *fmt, ...)
119 {
120 va_list args;
121
122 if (verbose <= DEFAULT_VERBOSE)
123 return;
124
125 va_start(args, fmt);
126 vfprintf(stdout, fmt, args);
127 fflush(stdout);
128 va_end(args);
129 }
130
131 static inline void _log(int prio, const char *fmt, ...)
132 {
133 const char *prioname;
134 char buf[32], *msg;
135 va_list args;
136
137 if (prio > verbose)
138 return;
139
140 va_start(args, fmt);
141 if (vasprintf(&msg, fmt, args) < 0)
142 msg = NULL;
143 va_end(args);
144 if (msg == NULL)
145 return;
146
147 switch (prio) {
148 case LOG_CRIT:
149 prioname = "FATAL";
150 break;
151 case LOG_ERR:
152 prioname = "ERROR";
153 break;
154 case LOG_WARNING:
155 prioname = "WARNING";
156 break;
157 case LOG_NOTICE:
158 prioname = "NOTICE";
159 break;
160 case LOG_INFO:
161 prioname = "INFO";
162 break;
163 case LOG_DEBUG:
164 prioname = "DEBUG";
165 break;
166 default:
167 snprintf(buf, sizeof(buf), "LOG-%03d", prio);
168 prioname = buf;
169 }
170
171 fprintf(stderr, "%s: %s", prioname, msg);
172 free(msg);
173
174 if (prio <= LOG_CRIT)
175 exit(EXIT_FAILURE);
176 }
177 #define CRIT(...) _log(LOG_CRIT, __VA_ARGS__)
178 #define ERR(...) _log(LOG_ERR, __VA_ARGS__)
179 #define WRN(...) _log(LOG_WARNING, __VA_ARGS__)
180 #define INF(...) _log(LOG_INFO, __VA_ARGS__)
181 #define DBG(...) _log(LOG_DEBUG, __VA_ARGS__)
182 #define SHOW(...) _show(__VA_ARGS__)
183
184
185 /* binary index write *************************************************/
186 #include <arpa/inet.h>
187 #include "macro.h"
188 /* BEGIN: code from module-init-tools/index.c just modified to compile here.
189 *
190 * Original copyright:
191 * index.c: module index file shared functions for modprobe and depmod
192 * Copyright (C) 2008 Alan Jenkins <alan-jenkins@tuffmail.co.uk>.
193 *
194 * These programs are free software; you can redistribute it and/or modify
195 * it under the terms of the GNU General Public License as published by
196 * the Free Software Foundation; either version 2 of the License, or
197 * (at your option) any later version.
198 *
199 * This program is distributed in the hope that it will be useful,
200 * but WITHOUT ANY WARRANTY; without even the implied warranty of
201 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
202 * GNU General Public License for more details.
203 *
204 * You should have received a copy of the GNU General Public License
205 * along with these programs. If not, see <http://www.gnu.org/licenses/>.
206 */
207
208 /* Integers are stored as 32 bit unsigned in "network" order, i.e. MSB first.
209 All files start with a magic number.
210
211 Magic spells "BOOTFAST". Second one used on newer versioned binary files.
212 */
213 /* #define INDEX_MAGIC_OLD 0xB007FA57 */
214 #define INDEX_MAGIC 0xB007F457
215
216 /* We use a version string to keep track of changes to the binary format
217 * This is stored in the form: INDEX_MAJOR (hi) INDEX_MINOR (lo) just in
218 * case we ever decide to have minor changes that are not incompatible.
219 */
220
221 #define INDEX_VERSION_MAJOR 0x0002
222 #define INDEX_VERSION_MINOR 0x0001
223 #define INDEX_VERSION ((INDEX_VERSION_MAJOR<<16)|INDEX_VERSION_MINOR)
224
225 /* The index file maps keys to values. Both keys and values are ASCII strings.
226 Each key can have multiple values. Values are sorted by an integer priority.
227
228 The reader also implements a wildcard search (including range expressions)
229 where the keys in the index are treated as patterns.
230 This feature is required for module aliases.
231 */
232
233 /* Implementation is based on a radix tree, or "trie".
234 Each arc from parent to child is labelled with a character.
235 Each path from the root represents a string.
236
237 == Example strings ==
238
239 ask
240 ate
241 on
242 once
243 one
244
245 == Key ==
246 + Normal node
247 * Marked node, representing a key and it's values.
248
249 +
250 |-a-+-s-+-k-*
251 | |
252 | `-t-+-e-*
253 |
254 `-o-+-n-*-c-+-e-*
255 |
256 `-e-*
257
258 Naive implementations tend to be very space inefficient; child pointers
259 are stored in arrays indexed by character, but most child pointers are null.
260
261 Our implementation uses a scheme described by Wikipedia as a Patrica trie,
262
263 "easiest to understand as a space-optimized trie where
264 each node with only one child is merged with its child"
265
266 +
267 |-a-+-sk-*
268 | |
269 | `-te-*
270 |
271 `-on-*-ce-*
272 |
273 `-e-*
274
275 We still use arrays of child pointers indexed by a single character;
276 the remaining characters of the label are stored as a "prefix" in the child.
277
278 The paper describing the original Patrica trie works on individiual bits -
279 each node has a maximum of two children, which increases space efficiency.
280 However for this application it is simpler to use the ASCII character set.
281 Since the index file is read-only, it can be compressed by omitting null
282 child pointers at the start and end of arrays.
283 */
284
285 #define INDEX_PRIORITY_MIN UINT32_MAX
286
287 struct index_value {
288 struct index_value *next;
289 unsigned int priority;
290 char value[0];
291 };
292
293 /* In-memory index (depmod only) */
294
295 #define INDEX_CHILDMAX 128
296 struct index_node {
297 char *prefix; /* path compression */
298 struct index_value *values;
299 unsigned char first; /* range of child nodes */
300 unsigned char last;
301 struct index_node *children[INDEX_CHILDMAX]; /* indexed by character */
302 };
303
304 /* Disk format:
305
306 uint32_t magic = INDEX_MAGIC;
307 uint32_t version = INDEX_VERSION;
308 uint32_t root_offset;
309
310 (node_offset & INDEX_NODE_MASK) specifies the file offset of nodes:
311
312 char[] prefix; // nul terminated
313
314 char first;
315 char last;
316 uint32_t children[last - first + 1];
317
318 uint32_t value_count;
319 struct {
320 uint32_t priority;
321 char[] value; // nul terminated
322 } values[value_count];
323
324 (node_offset & INDEX_NODE_FLAGS) indicates which fields are present.
325 Empty prefixes are omitted, leaf nodes omit the three child-related fields.
326
327 This could be optimised further by adding a sparse child format
328 (indicated using a new flag).
329 */
330
331 /* Format of node offsets within index file */
332 enum node_offset {
333 INDEX_NODE_FLAGS = 0xF0000000, /* Flags in high nibble */
334 INDEX_NODE_PREFIX = 0x80000000,
335 INDEX_NODE_VALUES = 0x40000000,
336 INDEX_NODE_CHILDS = 0x20000000,
337
338 INDEX_NODE_MASK = 0x0FFFFFFF, /* Offset value */
339 };
340
341 static struct index_node *index_create(void)
342 {
343 struct index_node *node;
344
345 node = NOFAIL(calloc(sizeof(struct index_node), 1));
346 node->prefix = NOFAIL(strdup(""));
347 node->first = INDEX_CHILDMAX;
348
349 return node;
350 }
351
352 static void index_values_free(struct index_value *values)
353 {
354 while (values) {
355 struct index_value *value = values;
356
357 values = value->next;
358 free(value);
359 }
360 }
361
362 static void index_destroy(struct index_node *node)
363 {
364 int c;
365
366 for (c = node->first; c <= node->last; c++) {
367 struct index_node *child = node->children[c];
368
369 if (child)
370 index_destroy(child);
371 }
372 index_values_free(node->values);
373 free(node->prefix);
374 free(node);
375 }
376
377 static void index__checkstring(const char *str)
378 {
379 int i;
380
381 for (i = 0; str[i]; i++) {
382 int ch = str[i];
383
384 if (ch >= INDEX_CHILDMAX)
385 CRIT("Module index: bad character '%c'=0x%x - only 7-bit ASCII is supported:"
386 "\n%s\n", (char) ch, (int) ch, str);
387 }
388 }
389
390 static int index_add_value(struct index_value **values,
391 const char *value, unsigned int priority)
392 {
393 struct index_value *v;
394 int duplicate = 0;
395 int len;
396
397 /* report the presence of duplicate values */
398 for (v = *values; v; v = v->next) {
399 if (streq(v->value, value))
400 duplicate = 1;
401 }
402
403 /* find position to insert value */
404 while (*values && (*values)->priority < priority)
405 values = &(*values)->next;
406
407 len = strlen(value);
408 v = NOFAIL(calloc(sizeof(struct index_value) + len + 1, 1));
409 v->next = *values;
410 v->priority = priority;
411 memcpy(v->value, value, len + 1);
412 *values = v;
413
414 return duplicate;
415 }
416
417 static int index_insert(struct index_node *node, const char *key,
418 const char *value, unsigned int priority)
419 {
420 int i = 0; /* index within str */
421 int ch;
422
423 index__checkstring(key);
424 index__checkstring(value);
425
426 while(1) {
427 int j; /* index within node->prefix */
428
429 /* Ensure node->prefix is a prefix of &str[i].
430 If it is not already, then we must split node. */
431 for (j = 0; node->prefix[j]; j++) {
432 ch = node->prefix[j];
433
434 if (ch != key[i+j]) {
435 char *prefix = node->prefix;
436 struct index_node *n;
437
438 /* New child is copy of node with prefix[j+1..N] */
439 n = NOFAIL(calloc(sizeof(struct index_node), 1));
440 memcpy(n, node, sizeof(struct index_node));
441 n->prefix = NOFAIL(strdup(&prefix[j+1]));
442
443 /* Parent has prefix[0..j], child at prefix[j] */
444 memset(node, 0, sizeof(struct index_node));
445 prefix[j] = '\0';
446 node->prefix = prefix;
447 node->first = ch;
448 node->last = ch;
449 node->children[ch] = n;
450
451 break;
452 }
453 }
454 /* j is now length of node->prefix */
455 i += j;
456
457 ch = key[i];
458 if(ch == '\0')
459 return index_add_value(&node->values, value, priority);
460
461 if (!node->children[ch]) {
462 struct index_node *child;
463
464 if (ch < node->first)
465 node->first = ch;
466 if (ch > node->last)
467 node->last = ch;
468 node->children[ch] = NOFAIL(calloc(sizeof(struct index_node), 1));
469
470 child = node->children[ch];
471 child->prefix = NOFAIL(strdup(&key[i+1]));
472 child->first = INDEX_CHILDMAX;
473 index_add_value(&child->values, value, priority);
474
475 return 0;
476 }
477
478 /* Descend into child node and continue */
479 node = node->children[ch];
480 i++;
481 }
482 }
483
484 static int index__haschildren(const struct index_node *node)
485 {
486 return node->first < INDEX_CHILDMAX;
487 }
488
489 /* Recursive post-order traversal
490
491 Pre-order would make for better read-side buffering / readahead / caching.
492 (post-order means you go backwards in the file as you descend the tree).
493 However, index reading is already fast enough.
494 Pre-order is simpler for writing, and depmod is already slow.
495 */
496 static uint32_t index_write__node(const struct index_node *node, FILE *out)
497 {
498 uint32_t *child_offs = NULL;
499 int child_count = 0;
500 long offset;
501
502 if (!node)
503 return 0;
504
505 /* Write children and save their offsets */
506 if (index__haschildren(node)) {
507 const struct index_node *child;
508 int i;
509
510 child_count = node->last - node->first + 1;
511 child_offs = NOFAIL(malloc(child_count * sizeof(uint32_t)));
512
513 for (i = 0; i < child_count; i++) {
514 child = node->children[node->first + i];
515 child_offs[i] = htonl(index_write__node(child, out));
516 }
517 }
518
519 /* Now write this node */
520 offset = ftell(out);
521
522 if (node->prefix[0]) {
523 fputs(node->prefix, out);
524 fputc('\0', out);
525 offset |= INDEX_NODE_PREFIX;
526 }
527
528 if (child_count) {
529 fputc(node->first, out);
530 fputc(node->last, out);
531 fwrite(child_offs, sizeof(uint32_t), child_count, out);
532 free(child_offs);
533 offset |= INDEX_NODE_CHILDS;
534 }
535
536 if (node->values) {
537 const struct index_value *v;
538 unsigned int value_count;
539 uint32_t u;
540
541 value_count = 0;
542 for (v = node->values; v != NULL; v = v->next)
543 value_count++;
544 u = htonl(value_count);
545 fwrite(&u, sizeof(u), 1, out);
546
547 for (v = node->values; v != NULL; v = v->next) {
548 u = htonl(v->priority);
549 fwrite(&u, sizeof(u), 1, out);
550 fputs(v->value, out);
551 fputc('\0', out);
552 }
553 offset |= INDEX_NODE_VALUES;
554 }
555
556 return offset;
557 }
558
559 static void index_write(const struct index_node *node, FILE *out)
560 {
561 long initial_offset, final_offset;
562 uint32_t u;
563
564 u = htonl(INDEX_MAGIC);
565 fwrite(&u, sizeof(u), 1, out);
566 u = htonl(INDEX_VERSION);
567 fwrite(&u, sizeof(u), 1, out);
568
569 /* Second word is reserved for the offset of the root node */
570 initial_offset = ftell(out);
571 u = 0;
572 fwrite(&u, sizeof(uint32_t), 1, out);
573
574 /* Dump trie */
575 u = htonl(index_write__node(node, out));
576
577 /* Update first word */
578 final_offset = ftell(out);
579 fseek(out, initial_offset, SEEK_SET);
580 fwrite(&u, sizeof(uint32_t), 1, out);
581 fseek(out, final_offset, SEEK_SET);
582 }
583
584 /* END: code from module-init-tools/index.c just modified to compile here.
585 */
586
587 /* utils (variants of libkmod-utils.c) *********************************/
588 static const char *underscores2(const char *input, char *output, size_t outputlen)
589 {
590 size_t i;
591
592 for (i = 0; input[i] != '\0' && i < outputlen - 1; i++) {
593 switch (input[i]) {
594 case '-':
595 output[i] = '_';
596 break;
597
598 case ']':
599 WRN("Unmatched bracket in %s\n", input);
600 return NULL;
601
602 case '[': {
603 size_t off = strcspn(input + i, "]");
604 if (input[i + off] == '\0') {
605 WRN("Unmatched bracket in %s\n", input);
606 return NULL;
607 }
608 memcpy(output + i, input + i, off + 1);
609 i += off;
610 break;
611 }
612
613 default:
614 output[i] = input[i];
615 }
616 }
617 output[i] = '\0';
618
619 return output;
620 }
621
622 /* configuration parsing **********************************************/
623 struct cfg_override {
624 struct cfg_override *next;
625 size_t len;
626 char path[];
627 };
628
629 struct cfg_search {
630 struct cfg_search *next;
631 uint8_t builtin;
632 size_t len;
633 char path[];
634 };
635
636 struct cfg {
637 const char *kversion;
638 char dirname[PATH_MAX];
639 size_t dirnamelen;
640 char sym_prefix;
641 uint8_t check_symvers;
642 uint8_t print_unknown;
643 uint8_t warn_dups;
644 struct cfg_override *overrides;
645 struct cfg_search *searches;
646 };
647
648 static int cfg_search_add(struct cfg *cfg, const char *path, uint8_t builtin)
649 {
650 struct cfg_search *s;
651 size_t len;
652
653 if (builtin)
654 len = 0;
655 else
656 len = strlen(path) + 1;
657
658 s = malloc(sizeof(struct cfg_search) + len);
659 if (s == NULL) {
660 ERR("search add: out of memory\n");
661 return -ENOMEM;
662 }
663 s->builtin = builtin;
664 if (builtin)
665 s->len = 0;
666 else {
667 s->len = len - 1;
668 memcpy(s->path, path, len);
669 }
670
671 DBG("search add: %s, builtin=%hhu\n", path, builtin);
672
673 s->next = cfg->searches;
674 cfg->searches = s;
675 return 0;
676 }
677
678 static void cfg_search_free(struct cfg_search *s)
679 {
680 free(s);
681 }
682
683 static int cfg_override_add(struct cfg *cfg, const char *modname, const char *subdir)
684 {
685 struct cfg_override *o;
686 size_t modnamelen = strlen(modname);
687 size_t subdirlen = strlen(subdir);
688 size_t i;
689
690 o = malloc(sizeof(struct cfg_override) + subdirlen + 1
691 + modnamelen + 1);
692 if (o == NULL) {
693 ERR("override add: out of memory\n");
694 return -ENOMEM;
695 }
696 memcpy(o->path, subdir, subdirlen);
697 i = subdirlen;
698 o->path[i] = '/';
699 i++;
700
701 memcpy(o->path + i, modname, modnamelen);
702 i += modnamelen;
703 o->path[i] = '\0'; /* no extension, so we can match .ko/.ko.gz */
704
705 o->len = i;
706
707 DBG("override add: %s\n", o->path);
708
709 o->next = cfg->overrides;
710 cfg->overrides = o;
711 return 0;
712 }
713
714 static void cfg_override_free(struct cfg_override *o)
715 {
716 free(o);
717 }
718
719 static int cfg_kernel_matches(const struct cfg *cfg, const char *pattern)
720 {
721 regex_t re;
722 int status;
723
724 /* old style */
725 if (streq(pattern, "*"))
726 return 1;
727
728 if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB) != 0)
729 return 0;
730
731 status = regexec(&re, cfg->kversion, 0, NULL, 0);
732 regfree(&re);
733
734 return status == 0;
735 }
736
737 static int cfg_file_parse(struct cfg *cfg, const char *filename)
738 {
739 char *line;
740 FILE *fp;
741 unsigned int linenum = 0;
742 int err;
743
744 fp = fopen(filename, "r");
745 if (fp == NULL) {
746 err = -errno;
747 ERR("file parse %s: %m\n", filename);
748 return err;
749 }
750
751 while ((line = getline_wrapped(fp, &linenum)) != NULL) {
752 char *cmd, *saveptr;
753
754 if (line[0] == '\0' || line[0] == '#')
755 goto done_next;
756
757 cmd = strtok_r(line, "\t ", &saveptr);
758 if (cmd == NULL)
759 goto done_next;
760
761 if (streq(cmd, "search")) {
762 const char *sp;
763 while ((sp = strtok_r(NULL, "\t ", &saveptr)) != NULL) {
764 uint8_t builtin = streq(sp, CFG_BUILTIN_KEY);
765 cfg_search_add(cfg, sp, builtin);
766 }
767 } else if (streq(cmd, "override")) {
768 const char *modname = strtok_r(NULL, "\t ", &saveptr);
769 const char *version = strtok_r(NULL, "\t ", &saveptr);
770 const char *subdir = strtok_r(NULL, "\t ", &saveptr);
771
772 if (modname == NULL || version == NULL ||
773 subdir == NULL)
774 goto syntax_error;
775
776 if (!cfg_kernel_matches(cfg, version)) {
777 INF("%s:%u: override kernel did not match %s\n",
778 filename, linenum, version);
779 goto done_next;
780 }
781
782 cfg_override_add(cfg, modname, subdir);
783 } else if (streq(cmd, "include")
784 || streq(cmd, "make_map_files")) {
785 INF("%s:%u: command %s not implemented yet\n",
786 filename, linenum, cmd);
787 } else {
788 syntax_error:
789 ERR("%s:%u: ignoring bad line starting with '%s'\n",
790 filename, linenum, cmd);
791 }
792
793 done_next:
794 free(line);
795 }
796
797 fclose(fp);
798
799 return 0;
800 }
801
802 static int cfg_files_filter_out(DIR *d, const char *dir, const char *name)
803 {
804 size_t len = strlen(name);
805 struct stat st;
806
807 if (name[0] == '.')
808 return 1;
809
810 if (len < 6 || !streq(name + len - 5, ".conf")) {
811 INF("All cfg files need .conf: %s/%s\n", dir, name);
812 return 1;
813 }
814
815 fstatat(dirfd(d), name, &st, 0);
816 if (S_ISDIR(st.st_mode)) {
817 ERR("Directories inside directories are not supported: %s/%s\n",
818 dir, name);
819 return 1;
820 }
821
822 return 0;
823 }
824
825 struct cfg_file {
826 size_t dirlen;
827 size_t namelen;
828 const char *name;
829 char path[];
830 };
831
832 static void cfg_file_free(struct cfg_file *f)
833 {
834 free(f);
835 }
836
837 static int cfg_files_insert_sorted(struct cfg_file ***p_files, size_t *p_n_files,
838 const char *dir, const char *name)
839 {
840 struct cfg_file **files, *f;
841 size_t i, n_files, namelen, dirlen;
842 void *tmp;
843
844 dirlen = strlen(dir);
845 if (name != NULL)
846 namelen = strlen(name);
847 else {
848 name = basename(dir);
849 namelen = strlen(name);
850 dirlen -= namelen + 1;
851 }
852
853 n_files = *p_n_files;
854 files = *p_files;
855 for (i = 0; i < n_files; i++) {
856 int cmp = strcmp(name, files[i]->name);
857 if (cmp == 0) {
858 DBG("Ignoring duplicate config file: %.*s/%s\n",
859 (int)dirlen, dir, name);
860 return -EEXIST;
861 } else if (cmp < 0)
862 break;
863 }
864
865 f = malloc(sizeof(struct cfg_file) + dirlen + namelen + 2);
866 if (f == NULL) {
867 ERR("files insert sorted: out of memory\n");
868 return -ENOMEM;
869 }
870
871 tmp = realloc(files, sizeof(struct cfg_file *) * (n_files + 1));
872 if (tmp == NULL) {
873 ERR("files insert sorted: out of memory\n");
874 free(f);
875 return -ENOMEM;
876 }
877 *p_files = files = tmp;
878
879 if (i < n_files) {
880 memmove(files + i + 1, files + i,
881 sizeof(struct cfg_file *) * (n_files - i));
882 }
883 files[i] = f;
884
885 f->dirlen = dirlen;
886 f->namelen = namelen;
887 f->name = f->path + dirlen + 1;
888 memcpy(f->path, dir, dirlen);
889 f->path[dirlen] = '/';
890 memcpy(f->path + dirlen + 1, name, namelen);
891 f->path[dirlen + 1 + namelen] = '\0';
892
893 *p_n_files = n_files + 1;
894 return 0;
895 }
896
897 /*
898 * Insert configuration files ignoring duplicates
899 */
900 static int cfg_files_list(struct cfg_file ***p_files, size_t *p_n_files,
901 const char *path)
902 {
903 DIR *d;
904 int err = 0;
905 struct stat st;
906
907 if (stat(path, &st) != 0) {
908 err = -errno;
909 DBG("could not stat '%s': %m\n", path);
910 return err;
911 }
912
913 if (S_ISREG(st.st_mode)) {
914 cfg_files_insert_sorted(p_files, p_n_files, path, NULL);
915 return 0;
916 } if (!S_ISDIR(st.st_mode)) {
917 ERR("unsupported file mode %s: %#x\n", path, st.st_mode);
918 return -EINVAL;
919 }
920
921 d = opendir(path);
922 if (d == NULL) {
923 ERR("files list %s: %m\n", path);
924 return -EINVAL;
925 }
926
927 for (;;) {
928 struct dirent ent, *entp;
929
930 err = readdir_r(d, &ent, &entp);
931 if (err != 0) {
932 ERR("reading entry %s\n", strerror(-err));
933 break;
934 }
935 if (entp == NULL)
936 break;
937 if (cfg_files_filter_out(d, path, entp->d_name))
938 continue;
939
940 cfg_files_insert_sorted(p_files, p_n_files, path, entp->d_name);
941 }
942
943 closedir(d);
944 DBG("parsed configuration files from %s\n", path);
945 return err;
946 }
947
948 static int cfg_load(struct cfg *cfg, const char * const *cfg_paths)
949 {
950 size_t i, n_files = 0;
951 struct cfg_file **files = NULL;
952
953 if (cfg_paths == NULL)
954 cfg_paths = default_cfg_paths;
955
956 for (i = 0; cfg_paths[i] != NULL; i++)
957 cfg_files_list(&files, &n_files, cfg_paths[i]);
958
959 for (i = 0; i < n_files; i++) {
960 struct cfg_file *f = files[i];
961 cfg_file_parse(cfg, f->path);
962 cfg_file_free(f);
963 }
964 free(files);
965
966 /* For backward compatibility add "updates" to the head of the search
967 * list here. But only if there was no "search" option specified.
968 */
969 if (cfg->searches == NULL)
970 cfg_search_add(cfg, "updates", 0);
971
972 return 0;
973 }
974
975 static void cfg_free(struct cfg *cfg)
976 {
977 while (cfg->overrides) {
978 struct cfg_override *tmp = cfg->overrides;
979 cfg->overrides = cfg->overrides->next;
980 cfg_override_free(tmp);
981 }
982
983 while (cfg->searches) {
984 struct cfg_search *tmp = cfg->searches;
985 cfg->searches = cfg->searches->next;
986 cfg_search_free(tmp);
987 }
988 }
989
990
991 /* depmod calculations ***********************************************/
992 struct mod {
993 struct kmod_module *kmod;
994 const char *path;
995 const char *relpath; /* path relative to '$ROOT/lib/modules/$VER/' */
996 struct array deps; /* struct symbol */
997 size_t baselen; /* points to start of basename/filename */
998 size_t modnamelen;
999 int sort_idx; /* sort index using modules.order */
1000 int dep_sort_idx; /* topological sort index */
1001 uint16_t idx; /* index in depmod->modules.array */
1002 uint16_t users; /* how many modules depend on this one */
1003 uint8_t dep_loop : 1;
1004 char modname[];
1005 };
1006
1007 struct symbol {
1008 struct mod *owner;
1009 uint64_t crc;
1010 char name[];
1011 };
1012
1013 struct depmod {
1014 const struct cfg *cfg;
1015 struct kmod_ctx *ctx;
1016 struct array modules;
1017 struct hash *modules_by_relpath;
1018 struct hash *modules_by_name;
1019 struct hash *symbols;
1020 unsigned int dep_loops;
1021 };
1022
1023 static void mod_free(struct mod *mod)
1024 {
1025 DBG("free %p kmod=%p, path=%s\n", mod, mod->kmod, mod->path);
1026 array_free_array(&mod->deps);
1027 kmod_module_unref(mod->kmod);
1028 free(mod);
1029 }
1030
1031 static int mod_add_dependency(struct mod *mod, struct symbol *sym)
1032 {
1033 int err;
1034
1035 DBG("%s depends on %s %s\n", mod->path, sym->name,
1036 sym->owner != NULL ? sym->owner->path : "(unknown)");
1037
1038 if (sym->owner == NULL)
1039 return 0;
1040
1041 err = array_append_unique(&mod->deps, sym->owner);
1042 if (err == -EEXIST)
1043 return 0;
1044 if (err < 0)
1045 return err;
1046
1047 sym->owner->users++;
1048 SHOW("%s needs \"%s\": %s\n", mod->path, sym->name, sym->owner->path);
1049 return 0;
1050 }
1051
1052 static void symbol_free(struct symbol *sym)
1053 {
1054 DBG("free %p sym=%s, owner=%p %s\n", sym, sym->name, sym->owner,
1055 sym->owner != NULL ? sym->owner->path : "");
1056 free(sym);
1057 }
1058
1059 static int depmod_init(struct depmod *depmod, struct cfg *cfg,
1060 struct kmod_ctx *ctx)
1061 {
1062 int err = 0;
1063
1064 depmod->cfg = cfg;
1065 depmod->ctx = ctx;
1066
1067 array_init(&depmod->modules, 128);
1068
1069 depmod->modules_by_relpath = hash_new(512, NULL);
1070 if (depmod->modules_by_relpath == NULL) {
1071 err = -errno;
1072 goto modules_by_relpath_failed;
1073 }
1074
1075 depmod->modules_by_name = hash_new(512, NULL);
1076 if (depmod->modules_by_name == NULL) {
1077 err = -errno;
1078 goto modules_by_name_failed;
1079 }
1080
1081 depmod->symbols = hash_new(2048, (void (*)(void *))symbol_free);
1082 if (depmod->symbols == NULL) {
1083 err = -errno;
1084 goto symbols_failed;
1085 }
1086
1087 return 0;
1088
1089 symbols_failed:
1090 hash_free(depmod->modules_by_name);
1091 modules_by_name_failed:
1092 hash_free(depmod->modules_by_relpath);
1093 modules_by_relpath_failed:
1094 return err;
1095 }
1096
1097 static void depmod_shutdown(struct depmod *depmod)
1098 {
1099 size_t i;
1100
1101 hash_free(depmod->symbols);
1102
1103 hash_free(depmod->modules_by_relpath);
1104
1105 hash_free(depmod->modules_by_name);
1106
1107 for (i = 0; i < depmod->modules.count; i++)
1108 mod_free(depmod->modules.array[i]);
1109 array_free_array(&depmod->modules);
1110
1111 kmod_unref(depmod->ctx);
1112 }
1113
1114 static int depmod_module_add(struct depmod *depmod, struct kmod_module *kmod)
1115 {
1116 const struct cfg *cfg = depmod->cfg;
1117 const char *modname;
1118 size_t modnamelen;
1119 struct mod *mod;
1120 int err;
1121
1122 modname = kmod_module_get_name(kmod);
1123 modnamelen = strlen(modname) + 1;
1124
1125 mod = calloc(1, sizeof(struct mod) + modnamelen);
1126 if (mod == NULL)
1127 return -ENOMEM;
1128 mod->kmod = kmod;
1129 mod->sort_idx = depmod->modules.count + 1;
1130 mod->dep_sort_idx = INT32_MAX;
1131 memcpy(mod->modname, modname, modnamelen);
1132 mod->modnamelen = modnamelen;
1133
1134 array_init(&mod->deps, 4);
1135
1136 mod->path = kmod_module_get_path(kmod);
1137 mod->baselen = strrchr(mod->path, '/') - mod->path;
1138 if (strncmp(mod->path, cfg->dirname, cfg->dirnamelen) == 0 &&
1139 mod->path[cfg->dirnamelen] == '/')
1140 mod->relpath = mod->path + cfg->dirnamelen + 1;
1141 else
1142 mod->relpath = NULL;
1143
1144 err = hash_add_unique(depmod->modules_by_name, mod->modname, mod);
1145 if (err < 0) {
1146 ERR("hash_add_unique %s: %s\n", mod->modname, strerror(-err));
1147 free(mod);
1148 return err;
1149 }
1150
1151 if (mod->relpath != NULL) {
1152 err = hash_add_unique(depmod->modules_by_relpath,
1153 mod->relpath, mod);
1154 if (err < 0) {
1155 ERR("hash_add_unique %s: %s\n",
1156 mod->relpath, strerror(-err));
1157 hash_del(depmod->modules_by_name, mod->modname);
1158 free(mod);
1159 return err;
1160 }
1161 }
1162
1163 DBG("add %p kmod=%p, path=%s\n", mod, kmod, mod->path);
1164
1165 return 0;
1166 }
1167
1168 static int depmod_module_del(struct depmod *depmod, struct mod *mod)
1169 {
1170 DBG("del %p kmod=%p, path=%s\n", mod, mod->kmod, mod->path);
1171
1172 if (mod->relpath != NULL)
1173 hash_del(depmod->modules_by_relpath, mod->relpath);
1174
1175 hash_del(depmod->modules_by_name, mod->modname);
1176
1177 mod_free(mod);
1178 return 0;
1179 }
1180
1181 /* returns if existing module @mod is higher priority than newpath.
1182 * note this is the inverse of module-init-tools is_higher_priority()
1183 */
1184 static int depmod_module_is_higher_priority(const struct depmod *depmod, const struct mod *mod, size_t baselen, size_t namelen, size_t modnamelen, const char *newpath)
1185 {
1186 const struct cfg *cfg = depmod->cfg;
1187 const struct cfg_override *ov;
1188 const struct cfg_search *se;
1189 size_t newlen = baselen + modnamelen;
1190 size_t oldlen = mod->baselen + mod->modnamelen;
1191 const char *oldpath = mod->path;
1192 int i, bprio = -1, oldprio = -1, newprio = -1;
1193
1194 assert(strncmp(newpath, cfg->dirname, cfg->dirnamelen) == 0);
1195 assert(strncmp(oldpath, cfg->dirname, cfg->dirnamelen) == 0);
1196
1197 newpath += cfg->dirnamelen + 1;
1198 newlen -= cfg->dirnamelen + 1;
1199 oldpath += cfg->dirnamelen + 1;
1200 oldlen -= cfg->dirnamelen + 1;
1201
1202 DBG("comparing priorities of %s and %s\n",
1203 oldpath, newpath);
1204
1205 for (ov = cfg->overrides; ov != NULL; ov = ov->next) {
1206 DBG("override %s\n", ov->path);
1207 if (newlen == ov->len && memcmp(ov->path, newpath, newlen) == 0)
1208 return 0;
1209 if (oldlen == ov->len && memcmp(ov->path, oldpath, oldlen) == 0)
1210 return 1;
1211 }
1212
1213 for (i = 0, se = cfg->searches; se != NULL; se = se->next, i++) {
1214 DBG("search %s\n", se->builtin ? "built-in" : se->path);
1215 if (se->builtin)
1216 bprio = i;
1217 else if (newlen >= se->len &&
1218 memcmp(se->path, newpath, se->len) == 0)
1219 newprio = i;
1220 else if (oldlen >= se->len &&
1221 memcmp(se->path, oldpath, se->len) == 0)
1222 oldprio = i;
1223 }
1224
1225 if (newprio < 0)
1226 newprio = bprio;
1227 if (oldprio < 0)
1228 oldprio = bprio;
1229
1230 DBG("priorities: built-in: %d, old: %d, new: %d\n",
1231 bprio, newprio, oldprio);
1232
1233 return newprio <= oldprio;
1234 }
1235
1236 static int depmod_modules_search_file(struct depmod *depmod, size_t baselen, size_t namelen, const char *path)
1237 {
1238 struct kmod_module *kmod;
1239 struct mod *mod;
1240 const char *relpath;
1241 char modname[PATH_MAX];
1242 const struct kmod_ext *eitr;
1243 size_t modnamelen;
1244 uint8_t matches = 0;
1245 int err;
1246
1247 for (eitr = kmod_exts; eitr->ext != NULL; eitr++) {
1248 if (namelen <= eitr->len)
1249 continue;
1250 if (streq(path + baselen + namelen - eitr->len, eitr->ext)) {
1251 matches = 1;
1252 break;
1253 }
1254 }
1255 if (!matches)
1256 return 0;
1257
1258 if (path_to_modname(path, modname, &modnamelen) == NULL) {
1259 ERR("could not get modname from path %s\n", path);
1260 return -EINVAL;
1261 }
1262
1263 relpath = path + depmod->cfg->dirnamelen + 1;
1264 DBG("try %s (%s)\n", relpath, modname);
1265
1266 mod = hash_find(depmod->modules_by_name, modname);
1267 if (mod == NULL)
1268 goto add;
1269
1270 if (depmod_module_is_higher_priority(depmod, mod, baselen,
1271 namelen, modnamelen, path)) {
1272 DBG("Ignored lower priority: %s, higher: %s\n",
1273 path, mod->path);
1274 return 0;
1275 }
1276
1277 DBG("Replace lower priority %s with new module %s\n",
1278 mod->relpath, relpath);
1279 err = depmod_module_del(depmod, mod);
1280 if (err < 0) {
1281 ERR("could not del module %s: %s\n", mod->path, strerror(-err));
1282 return err;
1283 }
1284
1285 add:
1286 err = kmod_module_new_from_path(depmod->ctx, path, &kmod);
1287 if (err < 0) {
1288 ERR("could not create module %s: %s\n", path, strerror(-err));
1289 return err;
1290 }
1291
1292 err = depmod_module_add(depmod, kmod);
1293 if (err < 0) {
1294 ERR("could not add module %s: %s\n",
1295 path, strerror(-err));
1296 kmod_module_unref(kmod);
1297 return err;
1298 }
1299 return 0;
1300 }
1301
1302 static int depmod_modules_search_dir(struct depmod *depmod, DIR *d, size_t baselen, char *path)
1303 {
1304 struct dirent *de;
1305 int err = 0, dfd = dirfd(d);
1306
1307 while ((de = readdir(d)) != NULL) {
1308 const char *name = de->d_name;
1309 size_t namelen;
1310 uint8_t is_dir;
1311
1312 if (name[0] == '.' && (name[1] == '\0' ||
1313 (name[1] == '.' && name[2] == '\0')))
1314 continue;
1315 if (streq(name, "build") || streq(name, "source"))
1316 continue;
1317 namelen = strlen(name);
1318 if (baselen + namelen + 2 >= PATH_MAX) {
1319 path[baselen] = '\0';
1320 ERR("path is too long %s%s %zd\n", path, name);
1321 continue;
1322 }
1323 memcpy(path + baselen, name, namelen + 1);
1324
1325 if (de->d_type == DT_REG)
1326 is_dir = 0;
1327 else if (de->d_type == DT_DIR)
1328 is_dir = 1;
1329 else {
1330 struct stat st;
1331 if (fstatat(dfd, name, &st, 0) < 0) {
1332 ERR("fstatat(%d, %s): %m\n", dfd, name);
1333 continue;
1334 } else if (S_ISREG(st.st_mode))
1335 is_dir = 0;
1336 else if (S_ISDIR(st.st_mode))
1337 is_dir = 1;
1338 else {
1339 ERR("unsupported file type %s: %o\n",
1340 path, st.st_mode & S_IFMT);
1341 continue;
1342 }
1343 }
1344
1345 if (is_dir) {
1346 int fd;
1347 DIR *subdir;
1348 if (baselen + namelen + 2 + NAME_MAX >= PATH_MAX) {
1349 ERR("directory path is too long %s\n", path);
1350 continue;
1351 }
1352 fd = openat(dfd, name, O_RDONLY);
1353 if (fd < 0) {
1354 ERR("openat(%d, %s, O_RDONLY): %m\n",
1355 dfd, name);
1356 continue;
1357 }
1358 subdir = fdopendir(fd);
1359 if (subdir == NULL) {
1360 ERR("fdopendir(%d): %m\n", fd);
1361 close(fd);
1362 continue;
1363 }
1364 path[baselen + namelen] = '/';
1365 path[baselen + namelen + 1] = '\0';
1366 err = depmod_modules_search_dir(depmod, subdir,
1367 baselen + namelen + 1,
1368 path);
1369 closedir(subdir);
1370 } else {
1371 err = depmod_modules_search_file(depmod, baselen,
1372 namelen, path);
1373 }
1374
1375 if (err < 0) {
1376 path[baselen + namelen] = '\0';
1377 ERR("failed %s: %s\n", path, strerror(-err));
1378 err = 0; /* ignore errors */
1379 }
1380 }
1381
1382 return err;
1383 }
1384
1385 static int depmod_modules_search(struct depmod *depmod)
1386 {
1387 char path[PATH_MAX];
1388 DIR *d = opendir(depmod->cfg->dirname);
1389 size_t baselen;
1390 int err;
1391 if (d == NULL) {
1392 err = -errno;
1393 ERR("could not open directory %s: %m\n", depmod->cfg->dirname);
1394 return err;
1395 }
1396
1397 baselen = depmod->cfg->dirnamelen;
1398 memcpy(path, depmod->cfg->dirname, baselen);
1399 path[baselen] = '/';
1400 baselen++;
1401 path[baselen] = '\0';
1402
1403 err = depmod_modules_search_dir(depmod, d, baselen, path);
1404 closedir(d);
1405 return err;
1406 }
1407
1408 static int mod_cmp(const void *pa, const void *pb) {
1409 const struct mod *a = *(const struct mod **)pa;
1410 const struct mod *b = *(const struct mod **)pb;
1411 if (a->dep_loop == b->dep_loop)
1412 return a->sort_idx - b->sort_idx;
1413 else if (a->dep_loop)
1414 return 1;
1415 else if (b->dep_loop)
1416 return -1;
1417 return a->sort_idx - b->sort_idx;
1418 }
1419
1420 static int depmod_modules_build_array(struct depmod *depmod)
1421 {
1422 struct hash_iter module_iter;
1423 const void *v;
1424 int err;
1425
1426 hash_iter_init(depmod->modules_by_name, &module_iter);
1427 while (hash_iter_next(&module_iter, NULL, &v)) {
1428 struct mod *mod = (struct mod *) v;
1429 mod->idx = depmod->modules.count;
1430 err = array_append(&depmod->modules, mod);
1431 if (err < 0)
1432 return err;
1433 }
1434
1435 return 0;
1436 }
1437
1438 static void depmod_modules_sort(struct depmod *depmod)
1439 {
1440 char order_file[PATH_MAX], line[PATH_MAX];
1441 FILE *fp;
1442 unsigned idx = 0, total = 0;
1443
1444 snprintf(order_file, sizeof(order_file), "%s/modules.order",
1445 depmod->cfg->dirname);
1446 fp = fopen(order_file, "r");
1447 if (fp == NULL) {
1448 WRN("could not open %s: %m\n", order_file);
1449 return;
1450 }
1451
1452 while (fgets(line, sizeof(line), fp) != NULL) {
1453 size_t len = strlen(line);
1454 idx++;
1455 if (len == 0)
1456 continue;
1457 if (line[len - 1] != '\n') {
1458 ERR("%s:%u corrupted line misses '\\n'\n",
1459 order_file, idx);
1460 goto corrupted;
1461 }
1462 }
1463 total = idx + 1;
1464 idx = 0;
1465 fseek(fp, 0, SEEK_SET);
1466 while (fgets(line, sizeof(line), fp) != NULL) {
1467 size_t len = strlen(line);
1468 struct mod *mod;
1469
1470 idx++;
1471 if (len == 0)
1472 continue;
1473 line[len - 1] = '\0';
1474
1475 mod = hash_find(depmod->modules_by_relpath, line);
1476 if (mod == NULL)
1477 continue;
1478 mod->sort_idx = idx - total;
1479 }
1480
1481 array_sort(&depmod->modules, mod_cmp);
1482 for (idx = 0; idx < depmod->modules.count; idx++) {
1483 struct mod *m = depmod->modules.array[idx];
1484 m->idx = idx;
1485 }
1486
1487 corrupted:
1488 fclose(fp);
1489 }
1490
1491 static int depmod_symbol_add(struct depmod *depmod, const char *name,
1492 uint64_t crc, const struct mod *owner)
1493 {
1494 size_t namelen;
1495 int err;
1496 struct symbol *sym;
1497
1498 if (name[0] == depmod->cfg->sym_prefix)
1499 name++;
1500
1501 namelen = strlen(name) + 1;
1502 sym = malloc(sizeof(struct symbol) + namelen);
1503 if (sym == NULL)
1504 return -ENOMEM;
1505
1506 sym->owner = (struct mod *)owner;
1507 sym->crc = crc;
1508 memcpy(sym->name, name, namelen);
1509
1510 err = hash_add(depmod->symbols, sym->name, sym);
1511 if (err < 0) {
1512 free(sym);
1513 return err;
1514 }
1515
1516 DBG("add %p sym=%s, owner=%p %s\n", sym, sym->name, owner,
1517 owner != NULL ? owner->path : "");
1518
1519 return 0;
1520 }
1521
1522 static struct symbol *depmod_symbol_find(const struct depmod *depmod,
1523 const char *name)
1524 {
1525 if (name[0] == '.') /* PPC64 needs this: .foo == foo */
1526 name++;
1527 if (name[0] == depmod->cfg->sym_prefix)
1528 name++;
1529 return hash_find(depmod->symbols, name);
1530 }
1531
1532 static int depmod_load_symbols(struct depmod *depmod)
1533 {
1534 const struct mod **itr, **itr_end;
1535
1536 DBG("load symbols (%zd modules)\n", depmod->modules.count);
1537
1538 itr = (const struct mod **)depmod->modules.array;
1539 itr_end = itr + depmod->modules.count;
1540 for (; itr < itr_end; itr++) {
1541 const struct mod *mod = *itr;
1542 struct kmod_list *l, *list = NULL;
1543 int err = kmod_module_get_symbols(mod->kmod, &list);
1544 if (err < 0) {
1545 if (err == -ENOENT)
1546 DBG("ignoring %s: no symbols\n", mod->path);
1547 else
1548 ERR("failed to load symbols from %s: %s\n",
1549 mod->path, strerror(-err));
1550 continue;
1551 }
1552 kmod_list_foreach(l, list) {
1553 const char *name = kmod_module_symbol_get_symbol(l);
1554 uint64_t crc = kmod_module_symbol_get_crc(l);
1555 depmod_symbol_add(depmod, name, crc, mod);
1556 }
1557 kmod_module_symbols_free_list(list);
1558 }
1559
1560 DBG("loaded symbols (%zd modules, %zd symbols)\n",
1561 depmod->modules.count, hash_get_count(depmod->symbols));
1562
1563 return 0;
1564 }
1565
1566 static int depmod_load_module_dependencies(struct depmod *depmod, struct mod *mod)
1567 {
1568 const struct cfg *cfg = depmod->cfg;
1569 struct kmod_list *l, *list = NULL;
1570 int err = kmod_module_get_dependency_symbols(mod->kmod, &list);
1571 if (err < 0) {
1572 DBG("ignoring %s: no dependency symbols: %s\n",
1573 mod->path, strerror(-err));
1574 return 0;
1575 }
1576
1577 DBG("do dependencies of %s\n", mod->path);
1578 kmod_list_foreach(l, list) {
1579 const char *name = kmod_module_dependency_symbol_get_symbol(l);
1580 uint64_t crc = kmod_module_dependency_symbol_get_crc(l);
1581 int bindtype = kmod_module_dependency_symbol_get_bind(l);
1582 struct symbol *sym = depmod_symbol_find(depmod, name);
1583 uint8_t is_weak = bindtype == KMOD_SYMBOL_WEAK;
1584
1585 if (sym == NULL) {
1586 DBG("%s needs (%c) unknown symbol %s\n",
1587 mod->path, bindtype, name);
1588 if (cfg->print_unknown && !is_weak)
1589 WRN("%s needs unknown symbol %s\n",
1590 mod->path, name);
1591 continue;
1592 }
1593
1594 if (cfg->check_symvers && sym->crc != crc && !is_weak) {
1595 DBG("symbol %s (%#"PRIx64") module %s (%#"PRIx64")\n",
1596 sym->name, sym->crc, mod->path, crc);
1597 if (cfg->print_unknown)
1598 WRN("%s disagrees about version of symbol %s\n",
1599 mod->path, name);
1600 }
1601
1602 mod_add_dependency(mod, sym);
1603 }
1604 kmod_module_dependency_symbols_free_list(list);
1605 return 0;
1606 }
1607
1608 static int depmod_load_dependencies(struct depmod *depmod)
1609 {
1610 struct mod **itr, **itr_end;
1611
1612 DBG("load dependencies (%zd modules, %zd symbols)\n",
1613 depmod->modules.count, hash_get_count(depmod->symbols));
1614
1615 itr = (struct mod **)depmod->modules.array;
1616 itr_end = itr + depmod->modules.count;
1617 for (; itr < itr_end; itr++) {
1618 struct mod *mod = *itr;
1619 depmod_load_module_dependencies(depmod, mod);
1620 }
1621
1622 DBG("loaded dependencies (%zd modules, %zd symbols)\n",
1623 depmod->modules.count, hash_get_count(depmod->symbols));
1624
1625 return 0;
1626 }
1627
1628 static int dep_cmp(const void *pa, const void *pb)
1629 {
1630 const struct mod *a = *(const struct mod **)pa;
1631 const struct mod *b = *(const struct mod **)pb;
1632 if (a->dep_loop == b->dep_loop)
1633 return a->dep_sort_idx - b->dep_sort_idx;
1634 else if (a->dep_loop)
1635 return 1;
1636 else if (b->dep_loop)
1637 return -1;
1638 return a->dep_sort_idx - b->dep_sort_idx;
1639 }
1640
1641 static void depmod_sort_dependencies(struct depmod *depmod)
1642 {
1643 struct mod **itr, **itr_end;
1644 itr = (struct mod **)depmod->modules.array;
1645 itr_end = itr + depmod->modules.count;
1646 for (; itr < itr_end; itr++) {
1647 struct mod *m = *itr;
1648 if (m->deps.count > 1)
1649 array_sort(&m->deps, dep_cmp);
1650 }
1651 }
1652
1653 static int depmod_calculate_dependencies(struct depmod *depmod)
1654 {
1655 const struct mod **itrm;
1656 uint16_t *users, *roots, *sorted;
1657 uint16_t i, n_roots = 0, n_sorted = 0, n_mods = depmod->modules.count;
1658
1659 users = malloc(sizeof(uint16_t) * n_mods * 3);
1660 if (users == NULL)
1661 return -ENOMEM;
1662 roots = users + n_mods;
1663 sorted = roots + n_mods;
1664
1665 DBG("calculate dependencies and ordering (%zd modules)\n", n_mods);
1666
1667 assert(depmod->modules.count < UINT16_MAX);
1668
1669 /* populate modules users (how many modules uses it) */
1670 itrm = (const struct mod **)depmod->modules.array;
1671 for (i = 0; i < n_mods; i++, itrm++) {
1672 const struct mod *m = *itrm;
1673 users[i] = m->users;
1674 if (users[i] == 0) {
1675 roots[n_roots] = i;
1676 n_roots++;
1677 }
1678 }
1679
1680 /* topological sort (outputs modules without users first) */
1681 while (n_roots > 0) {
1682 const struct mod **itr_dst, **itr_dst_end;
1683 struct mod *src;
1684 uint16_t src_idx = roots[--n_roots];
1685
1686 src = depmod->modules.array[src_idx];
1687 src->dep_sort_idx = n_sorted;
1688 sorted[n_sorted] = src_idx;
1689 n_sorted++;
1690
1691 itr_dst = (const struct mod **)src->deps.array;
1692 itr_dst_end = itr_dst + src->deps.count;
1693 for (; itr_dst < itr_dst_end; itr_dst++) {
1694 const struct mod *dst = *itr_dst;
1695 uint16_t dst_idx = dst->idx;
1696 assert(users[dst_idx] > 0);
1697 users[dst_idx]--;
1698 if (users[dst_idx] == 0) {
1699 roots[n_roots] = dst_idx;
1700 n_roots++;
1701 }
1702 }
1703 }
1704
1705 if (n_sorted < n_mods) {
1706 WRN("found %hu modules in dependency cycles!\n",
1707 n_mods - n_sorted);
1708 for (i = 0; i < n_mods; i++) {
1709 struct mod *m;
1710 if (users[i] == 0)
1711 continue;
1712 m = depmod->modules.array[i];
1713 WRN("%s in dependency cycle!\n", m->path);
1714 m->dep_loop = 1;
1715 m->dep_sort_idx = INT32_MAX;
1716 depmod->dep_loops++;
1717 }
1718 }
1719
1720 depmod_sort_dependencies(depmod);
1721
1722 DBG("calculated dependencies and ordering (%u loops, %zd modules)\n",
1723 depmod->dep_loops, n_mods);
1724
1725 free(users);
1726 return 0;
1727 }
1728
1729 static int depmod_load(struct depmod *depmod)
1730 {
1731 int err;
1732
1733 err = depmod_load_symbols(depmod);
1734 if (err < 0)
1735 return err;
1736
1737 err = depmod_load_dependencies(depmod);
1738 if (err < 0)
1739 return err;
1740
1741 err = depmod_calculate_dependencies(depmod);
1742 if (err < 0)
1743 return err;
1744
1745 return 0;
1746 }
1747
1748 static size_t mod_count_all_dependencies(const struct mod *mod)
1749 {
1750 size_t i, count = 0;
1751 for (i = 0; i < mod->deps.count; i++) {
1752 const struct mod *d = mod->deps.array[i];
1753 count += 1 + mod_count_all_dependencies(d);
1754 }
1755 return count;
1756 }
1757
1758 static int mod_fill_all_unique_dependencies(const struct mod *mod, const struct mod **deps, size_t n_deps, size_t *last)
1759 {
1760 size_t i;
1761 int err = 0;
1762 for (i = 0; i < mod->deps.count; i++) {
1763 const struct mod *d = mod->deps.array[i];
1764 size_t j;
1765 uint8_t exists = 0;
1766
1767 for (j = 0; j < *last; j++) {
1768 if (deps[j] == d) {
1769 exists = 1;
1770 break;
1771 }
1772 }
1773
1774 if (exists)
1775 continue;
1776
1777 if (*last >= n_deps)
1778 return -ENOSPC;
1779 deps[*last] = d;
1780 (*last)++;
1781 err = mod_fill_all_unique_dependencies(d, deps, n_deps, last);
1782 if (err < 0)
1783 break;
1784 }
1785 return err;
1786 }
1787
1788 static const struct mod **mod_get_all_sorted_dependencies(const struct mod *mod, size_t *n_deps)
1789 {
1790 const struct mod **deps;
1791 size_t last = 0;
1792
1793 *n_deps = mod_count_all_dependencies(mod);
1794 if (*n_deps == 0)
1795 return NULL;
1796
1797 deps = malloc(sizeof(struct mod *) * (*n_deps));
1798 if (deps == NULL)
1799 return NULL;
1800
1801 if (mod_fill_all_unique_dependencies(mod, deps, *n_deps, &last) < 0) {
1802 free(deps);
1803 return NULL;
1804 }
1805
1806 qsort(deps, last, sizeof(struct mod *), dep_cmp);
1807 *n_deps = last;
1808 return deps;
1809 }
1810
1811 static inline const char *mod_get_compressed_path(const struct mod *mod)
1812 {
1813 if (mod->relpath != NULL)
1814 return mod->relpath;
1815 return mod->path;
1816 }
1817
1818 static int output_deps(struct depmod *depmod, FILE *out)
1819 {
1820 size_t i;
1821
1822 for (i = 0; i < depmod->modules.count; i++) {
1823 const struct mod **deps, *mod = depmod->modules.array[i];
1824 const char *p = mod_get_compressed_path(mod);
1825 size_t j, n_deps;
1826
1827 if (mod->dep_loop) {
1828 DBG("Ignored %s due dependency loops\n", p);
1829 continue;
1830 }
1831
1832 fprintf(out, "%s:", p);
1833
1834 if (mod->deps.count == 0)
1835 goto end;
1836
1837 deps = mod_get_all_sorted_dependencies(mod, &n_deps);
1838 if (deps == NULL) {
1839 ERR("could not get all sorted dependencies of %s\n", p);
1840 goto end;
1841 }
1842
1843 for (j = 0; j < n_deps; j++) {
1844 const struct mod *d = deps[j];
1845 if (d->dep_loop) {
1846 DBG("Ignored %s (dependency of %s) "
1847 "due dependency loops\n",
1848 mod_get_compressed_path(d), p);
1849 continue;
1850 }
1851 fprintf(out, " %s", mod_get_compressed_path(d));
1852 }
1853 free(deps);
1854 end:
1855 putc('\n', out);
1856 }
1857
1858 return 0;
1859 }
1860
1861 static int output_deps_bin(struct depmod *depmod, FILE *out)
1862 {
1863 struct index_node *idx;
1864 size_t i;
1865
1866 if (out == stdout)
1867 return 0;
1868
1869 idx = index_create();
1870 if (idx == NULL)
1871 return -ENOMEM;
1872
1873 for (i = 0; i < depmod->modules.count; i++) {
1874 const struct mod **deps, *mod = depmod->modules.array[i];
1875 const char *p = mod_get_compressed_path(mod);
1876 char *line;
1877 size_t j, n_deps, linepos, linelen, slen;
1878 int duplicate;
1879
1880 if (mod->dep_loop) {
1881 DBG("Ignored %s due dependency loops\n", p);
1882 continue;
1883 }
1884
1885 deps = mod_get_all_sorted_dependencies(mod, &n_deps);
1886 if (deps == NULL && n_deps > 0) {
1887 ERR("could not get all sorted dependencies of %s\n", p);
1888 continue;
1889 }
1890
1891 linelen = strlen(p) + 1;
1892 for (j = 0; j < n_deps; j++) {
1893 const struct mod *d = deps[j];
1894 if (d->dep_loop) {
1895 DBG("Ignored %s (dependency of %s) "
1896 "due dependency loops\n",
1897 mod_get_compressed_path(d), p);
1898 continue;
1899 }
1900 linelen += 1 + strlen(mod_get_compressed_path(d));
1901 }
1902
1903 line = malloc(linelen + 1);
1904 if (line == NULL) {
1905 free(deps);
1906 ERR("modules.deps.bin: out of memory\n");
1907 continue;
1908 }
1909
1910 linepos = 0;
1911 slen = strlen(p);
1912 memcpy(line + linepos, p, slen);
1913 linepos += slen;
1914 line[linepos] = ':';
1915 linepos++;
1916
1917 for (j = 0; j < n_deps; j++) {
1918 const struct mod *d = deps[j];
1919 const char *dp;
1920 if (d->dep_loop)
1921 continue;
1922 line[linepos] = ' ';
1923 linepos++;
1924
1925 dp = mod_get_compressed_path(d);
1926 slen = strlen(dp);
1927 memcpy(line + linepos, dp, slen);
1928 linepos += slen;
1929 }
1930 line[linepos] = '\0';
1931
1932 duplicate = index_insert(idx, mod->modname, line, mod->idx);
1933 if (duplicate && depmod->cfg->warn_dups)
1934 WRN("duplicate module deps:\n%s\n", line);
1935 free(line);
1936 free(deps);
1937 }
1938
1939 index_write(idx, out);
1940 index_destroy(idx);
1941
1942 return 0;
1943 }
1944
1945 static int output_aliases(struct depmod *depmod, FILE *out)
1946 {
1947 size_t i;
1948
1949 fputs("# Aliases extracted from modules themselves.\n", out);
1950
1951 for (i = 0; i < depmod->modules.count; i++) {
1952 const struct mod *mod = depmod->modules.array[i];
1953 struct kmod_list *l, *list = NULL;
1954 int r = kmod_module_get_info(mod->kmod, &list);
1955 if (r < 0 || list == NULL)
1956 continue;
1957 kmod_list_foreach(l, list) {
1958 const char *key = kmod_module_info_get_key(l);
1959 const char *value = kmod_module_info_get_value(l);
1960
1961 if (!streq(key, "alias"))
1962 continue;
1963
1964 fprintf(out, "alias %s %s\n",
1965 value, kmod_module_get_name(mod->kmod));
1966 }
1967 kmod_module_info_free_list(list);
1968 }
1969
1970 return 0;
1971 }
1972
1973 static int output_aliases_bin(struct depmod *depmod, FILE *out)
1974 {
1975 char buf[1024];
1976 struct index_node *idx;
1977 size_t i;
1978
1979 if (out == stdout)
1980 return 0;
1981
1982 idx = index_create();
1983 if (idx == NULL)
1984 return -ENOMEM;
1985
1986 for (i = 0; i < depmod->modules.count; i++) {
1987 const struct mod *mod = depmod->modules.array[i];
1988 struct kmod_list *l, *list = NULL;
1989 int r = kmod_module_get_info(mod->kmod, &list);
1990 if (r < 0 || list == NULL)
1991 continue;
1992 kmod_list_foreach(l, list) {
1993 const char *key = kmod_module_info_get_key(l);
1994 const char *value = kmod_module_info_get_value(l);
1995 const char *modname, *alias;
1996 int duplicate;
1997
1998 if (!streq(key, "alias"))
1999 continue;
2000
2001 alias = underscores2(value, buf, sizeof(buf));
2002 if (alias == NULL)
2003 continue;
2004
2005 modname = kmod_module_get_name(mod->kmod);
2006 duplicate = index_insert(idx, alias, modname,
2007 mod->idx);
2008 if (duplicate && depmod->cfg->warn_dups)
2009 WRN("duplicate module alias:\n%s %s\n",
2010 alias, modname);
2011 }
2012 kmod_module_info_free_list(list);
2013 }
2014
2015 index_write(idx, out);
2016 index_destroy(idx);
2017
2018 return 0;
2019 }
2020
2021 static int output_softdeps(struct depmod *depmod, FILE *out)
2022 {
2023 size_t i;
2024
2025 fputs("# Soft dependencies extracted from modules themselves.\n", out);
2026 fputs("# Copy, with a .conf extension, to /etc/modprobe.d to use "
2027 "it with modprobe.\n", out);
2028
2029 for (i = 0; i < depmod->modules.count; i++) {
2030 const struct mod *mod = depmod->modules.array[i];
2031 struct kmod_list *l, *list = NULL;
2032 int r = kmod_module_get_info(mod->kmod, &list);
2033 if (r < 0 || list == NULL)
2034 continue;
2035 kmod_list_foreach(l, list) {
2036 const char *key = kmod_module_info_get_key(l);
2037 const char *value = kmod_module_info_get_value(l);
2038
2039 if (!streq(key, "softdep"))
2040 continue;
2041
2042 fprintf(out, "softdep %s %s\n",
2043 kmod_module_get_name(mod->kmod), value);
2044 }
2045 kmod_module_info_free_list(list);
2046 }
2047
2048 return 0;
2049 }
2050
2051 static int output_symbols(struct depmod *depmod, FILE *out)
2052 {
2053 struct hash_iter iter;
2054 const void *v;
2055
2056 fputs("# Aliases for symbols, used by symbol_request().\n", out);
2057
2058 hash_iter_init(depmod->symbols, &iter);
2059
2060 while (hash_iter_next(&iter, NULL, &v)) {
2061 const struct symbol *sym = v;
2062 if (sym->owner == NULL)
2063 continue;
2064
2065 fprintf(out, "alias symbol:%s %s\n",
2066 sym->name, sym->owner->modname);
2067 }
2068
2069 return 0;
2070 }
2071
2072 static int output_symbols_bin(struct depmod *depmod, FILE *out)
2073 {
2074 struct index_node *idx;
2075 char alias[1024];
2076 size_t baselen = sizeof("symbol:") - 1;
2077 struct hash_iter iter;
2078 const void *v;
2079
2080 if (out == stdout)
2081 return 0;
2082
2083 idx = index_create();
2084 if (idx == NULL)
2085 return -ENOMEM;
2086
2087 memcpy(alias, "symbol:", baselen);
2088 hash_iter_init(depmod->symbols, &iter);
2089
2090 while (hash_iter_next(&iter, NULL, &v)) {
2091 int duplicate;
2092 const struct symbol *sym = v;
2093
2094 if (sym->owner == NULL)
2095 continue;
2096
2097 strcpy(alias + baselen, sym->name);
2098 duplicate = index_insert(idx, alias, sym->owner->modname,
2099 sym->owner->idx);
2100
2101 if (duplicate && depmod->cfg->warn_dups)
2102 WRN("duplicate module syms:\n%s %s\n",
2103 alias, sym->owner->modname);
2104 }
2105
2106 index_write(idx, out);
2107 index_destroy(idx);
2108
2109 return 0;
2110 }
2111
2112 static int output_builtin_bin(struct depmod *depmod, FILE *out)
2113 {
2114 FILE *in;
2115 struct index_node *idx;
2116 char infile[PATH_MAX], line[PATH_MAX], modname[PATH_MAX];
2117
2118 if (out == stdout)
2119 return 0;
2120
2121 snprintf(infile, sizeof(infile), "%s/modules.builtin",
2122 depmod->cfg->dirname);
2123 in = fopen(infile, "r");
2124 if (in == NULL) {
2125 int err = -errno;
2126 WRN("could not open %s: %m\n", infile);
2127 return err;
2128 }
2129
2130 idx = index_create();
2131 if (idx == NULL) {
2132 fclose(in);
2133 return -ENOMEM;
2134 }
2135
2136 while (fgets(line, sizeof(line), in) != NULL) {
2137 if (!isalpha(line[0])) {
2138 ERR("Invalid modules.builtin line: %s\n", line);
2139 continue;
2140 }
2141
2142 path_to_modname(line, modname, NULL);
2143 index_insert(idx, modname, "", 0);
2144 }
2145
2146 index_write(idx, out);
2147 index_destroy(idx);
2148 fclose(in);
2149
2150 return 0;
2151 }
2152
2153 static int output_devname(struct depmod *depmod, FILE *out)
2154 {
2155 size_t i;
2156
2157 fputs("# Device nodes to trigger on-demand module loading.\n", out);
2158
2159 for (i = 0; i < depmod->modules.count; i++) {
2160 const struct mod *mod = depmod->modules.array[i];
2161 struct kmod_list *l, *list = NULL;
2162 const char *devname = NULL;
2163 char type = '\0';
2164 unsigned int major = 0, minor = 0;
2165 int r;
2166
2167 r = kmod_module_get_info(mod->kmod, &list);
2168 if (r < 0 || list == NULL)
2169 continue;
2170
2171 kmod_list_foreach(l, list) {
2172 const char *key = kmod_module_info_get_key(l);
2173 const char *value = kmod_module_info_get_value(l);
2174 unsigned int maj, min;
2175
2176 if (!streq(key, "alias"))
2177 continue;
2178
2179 if (strstartswith(value, "devname:"))
2180 devname = value + sizeof("devname:") - 1;
2181 else if (sscanf(value, "char-major-%u-%u",
2182 &maj, &min) == 2) {
2183 type = 'c';
2184 major = maj;
2185 minor = min;
2186 } else if (sscanf(value, "block-major-%u-%u",
2187 &maj, &min) == 2) {
2188 type = 'b';
2189 major = maj;
2190 minor = min;
2191 }
2192
2193 if (type != '\0' && devname != NULL) {
2194 fprintf(out, "%s %s %c%u:%u\n",
2195 kmod_module_get_name(mod->kmod),
2196 devname, type, major, minor);
2197 break;
2198 }
2199 }
2200 kmod_module_info_free_list(list);
2201 }
2202
2203 return 0;
2204 }
2205
2206 static int depmod_output(struct depmod *depmod, FILE *out)
2207 {
2208 static const struct depfile {
2209 const char *name;
2210 int (*cb)(struct depmod *depmod, FILE *out);
2211 } *itr, depfiles[] = {
2212 {"modules.dep", output_deps},
2213 {"modules.dep.bin", output_deps_bin},
2214 {"modules.alias", output_aliases},
2215 {"modules.alias.bin", output_aliases_bin},
2216 {"modules.softdep", output_softdeps},
2217 {"modules.symbols", output_symbols},
2218 {"modules.symbols.bin", output_symbols_bin},
2219 {"modules.builtin.bin", output_builtin_bin},
2220 {"modules.devname", output_devname},
2221 {NULL, NULL}
2222 };
2223 const char *dname = depmod->cfg->dirname;
2224 int dfd, err = 0;
2225
2226 if (out != NULL)
2227 dfd = -1;
2228 else {
2229 dfd = open(dname, O_RDONLY);
2230 if (dfd < 0) {
2231 err = -errno;
2232 CRIT("could not open directory %s: %m\n", dname);
2233 return err;
2234 }
2235 }
2236
2237 for (itr = depfiles; itr->name != NULL; itr++) {
2238 FILE *fp = out;
2239 char tmp[NAME_MAX] = "";
2240 int r;
2241
2242 if (fp == NULL) {
2243 int flags = O_CREAT | O_TRUNC | O_WRONLY;
2244 int mode = 0644;
2245 int fd;
2246
2247 snprintf(tmp, sizeof(tmp), "%s.tmp", itr->name);
2248 fd = openat(dfd, tmp, flags, mode);
2249 if (fd < 0) {
2250 ERR("openat(%s, %s, %o, %o): %m\n",
2251 dname, tmp, flags, mode);
2252 continue;
2253 }
2254 fp = fdopen(fd, "wb");
2255 if (fp == NULL) {
2256 ERR("fdopen(%d=%s/%s): %m\n", fd, dname, tmp);
2257 close(fd);
2258 continue;
2259 }
2260 }
2261
2262 r = itr->cb(depmod, fp);
2263 if (fp == out)
2264 continue;
2265
2266 fclose(fp);
2267 if (r < 0) {
2268 if (unlinkat(dfd, tmp, 0) != 0)
2269 ERR("unlinkat(%s, %s): %m\n", dname, tmp);
2270 } else {
2271 unlinkat(dfd, itr->name, 0);
2272 if (renameat(dfd, tmp, dfd, itr->name) != 0) {
2273 err = -errno;
2274 CRIT("renameat(%s, %s, %s, %s): %m\n",
2275 dname, tmp, dname, itr->name);
2276 break;
2277 }
2278 }
2279 }
2280
2281 if (dfd >= 0)
2282 close(dfd);
2283 return err;
2284 }
2285
2286 static void depmod_add_fake_syms(struct depmod *depmod)
2287 {
2288 /* __this_module is magic inserted by kernel loader. */
2289 depmod_symbol_add(depmod, "__this_module", 0, NULL);
2290 /* On S390, this is faked up too */
2291 depmod_symbol_add(depmod, "_GLOBAL_OFFSET_TABLE_", 0, NULL);
2292 }
2293
2294 static int depmod_load_symvers(struct depmod *depmod, const char *filename)
2295 {
2296 char line[10240];
2297 FILE *fp;
2298 unsigned int linenum = 0;
2299
2300 fp = fopen(filename, "r");
2301 if (fp == NULL) {
2302 int err = -errno;
2303 DBG("load symvers: %s: %m\n", filename);
2304 return err;
2305 }
2306 DBG("load symvers: %s\n", filename);
2307
2308 /* eg. "0xb352177e\tfind_first_bit\tvmlinux\tEXPORT_SYMBOL" */
2309 while (fgets(line, sizeof(line), fp) != NULL) {
2310 const char *ver, *sym, *where;
2311 char *verend;
2312 uint64_t crc;
2313
2314 linenum++;
2315
2316 ver = strtok(line, " \t");
2317 sym = strtok(NULL, " \t");
2318 where = strtok(NULL, " \t");
2319 if (!ver || !sym || !where)
2320 continue;
2321
2322 if (!streq(where, "vmlinux"))
2323 continue;
2324
2325 crc = strtoull(ver, &verend, 16);
2326 if (verend[0] != '\0') {
2327 ERR("%s:%u Invalid symbol version %s: %m\n",
2328 filename, linenum, ver);
2329 continue;
2330 }
2331
2332 depmod_symbol_add(depmod, sym, crc, NULL);
2333 }
2334 depmod_add_fake_syms(depmod);
2335
2336 DBG("loaded symvers: %s\n", filename);
2337
2338 fclose(fp);
2339 return 0;
2340 }
2341
2342 static int depmod_load_system_map(struct depmod *depmod, const char *filename)
2343 {
2344 const char ksymstr[] = "__ksymtab_";
2345 const size_t ksymstr_len = sizeof(ksymstr) - 1;
2346 char line[10240];
2347 FILE *fp;
2348 unsigned int linenum = 0;
2349
2350 fp = fopen(filename, "r");
2351 if (fp == NULL) {
2352 int err = -errno;
2353 DBG("load System.map: %s: %m\n", filename);
2354 return err;
2355 }
2356 DBG("load System.map: %s\n", filename);
2357
2358 /* eg. c0294200 R __ksymtab_devfs_alloc_devnum */
2359 while (fgets(line, sizeof(line), fp) != NULL) {
2360 char *p, *end;
2361
2362 linenum++;
2363
2364 p = strchr(line, ' ');
2365 if (p == NULL)
2366 goto invalid_syntax;
2367 p++;
2368 p = strchr(p, ' ');
2369 if (p == NULL)
2370 goto invalid_syntax;
2371 p++;
2372
2373 /* Covers gpl-only and normal symbols. */
2374 if (strncmp(p, ksymstr, ksymstr_len) != 0)
2375 continue;
2376
2377 end = strchr(p, '\n');
2378 if (end != NULL)
2379 *end = '\0';
2380
2381 depmod_symbol_add(depmod, p + ksymstr_len, 0, NULL);
2382 continue;
2383
2384 invalid_syntax:
2385 ERR("%s:%u: invalid line: %s\n", filename, linenum, line);
2386 }
2387 depmod_add_fake_syms(depmod);
2388
2389 DBG("loaded System.map: %s\n", filename);
2390
2391 fclose(fp);
2392 return 0;
2393 }
2394
2395
2396 static int depfile_up_to_date_dir(DIR *d, time_t mtime, size_t baselen, char *path)
2397 {
2398 struct dirent *de;
2399 int err = 1, dfd = dirfd(d);
2400
2401 while ((de = readdir(d)) != NULL) {
2402 const char *name = de->d_name;
2403 size_t namelen;
2404 struct stat st;
2405
2406 if (name[0] == '.' && (name[1] == '\0' ||
2407 (name[1] == '.' && name[2] == '\0')))
2408 continue;
2409 if (streq(name, "build") || streq(name, "source"))
2410 continue;
2411 namelen = strlen(name);
2412 if (baselen + namelen + 2 >= PATH_MAX) {
2413 path[baselen] = '\0';
2414 ERR("path is too long %s%s %zd\n", path, name);
2415 continue;
2416 }
2417
2418 if (fstatat(dfd, name, &st, 0) < 0) {
2419 ERR("fstatat(%d, %s): %m\n", dfd, name);
2420 continue;
2421 }
2422
2423 if (S_ISDIR(st.st_mode)) {
2424 int fd;
2425 DIR *subdir;
2426 memcpy(path + baselen, name, namelen + 1);
2427 if (baselen + namelen + 2 + NAME_MAX >= PATH_MAX) {
2428 ERR("directory path is too long %s\n", path);
2429 continue;
2430 }
2431 fd = openat(dfd, name, O_RDONLY);
2432 if (fd < 0) {
2433 ERR("openat(%d, %s, O_RDONLY): %m\n",
2434 dfd, name);
2435 continue;
2436 }
2437 subdir = fdopendir(fd);
2438 if (subdir == NULL) {
2439 ERR("fdopendir(%d): %m\n", fd);
2440 close(fd);
2441 continue;
2442 }
2443 path[baselen + namelen] = '/';
2444 path[baselen + namelen + 1] = '\0';
2445 err = depfile_up_to_date_dir(subdir, mtime,
2446 baselen + namelen + 1,
2447 path);
2448 closedir(subdir);
2449 } else if (S_ISREG(st.st_mode)) {
2450 const struct kmod_ext *eitr;
2451 uint8_t matches = 0;
2452 for (eitr = kmod_exts; eitr->ext != NULL; eitr++) {
2453 if (namelen <= eitr->len)
2454 continue;
2455 if (streq(name + namelen - eitr->len, eitr->ext)) {
2456 matches = 1;
2457 break;
2458 }
2459 }
2460 if (!matches)
2461 continue;
2462 memcpy(path + baselen, name, namelen + 1);
2463 err = st.st_mtime <= mtime;
2464 if (err == 0) {
2465 DBG("%s %"PRIu64" is newer than %"PRIu64"\n",
2466 path, (uint64_t)st.st_mtime,
2467 (uint64_t)mtime);
2468 }
2469 } else {
2470 ERR("unsupported file type %s: %o\n",
2471 path, st.st_mode & S_IFMT);
2472 continue;
2473 }
2474
2475 if (err == 0)
2476 break; /* outdated! */
2477 else if (err < 0) {
2478 path[baselen + namelen] = '\0';
2479 ERR("failed %s: %s\n", path, strerror(-err));
2480 err = 1; /* ignore errors */
2481 }
2482 }
2483
2484 return err;
2485 }
2486
2487 /* uptodate: 1, outdated: 0, errors < 0 */
2488 static int depfile_up_to_date(const char *dirname)
2489 {
2490 char path[PATH_MAX];
2491 DIR *d = opendir(dirname);
2492 struct stat st;
2493 size_t baselen;
2494 int err;
2495 if (d == NULL) {
2496 err = -errno;
2497 ERR("could not open directory %s: %m\n", dirname);
2498 return err;
2499 }
2500
2501 if (fstatat(dirfd(d), "modules.dep", &st, 0) != 0) {
2502 err = -errno;
2503 ERR("could not fstatat(%s, modules.dep): %m\n", dirname);
2504 closedir(d);
2505 return err;
2506 }
2507
2508 baselen = strlen(dirname);
2509 memcpy(path, dirname, baselen);
2510 path[baselen] = '/';
2511 baselen++;
2512 path[baselen] = '\0';
2513
2514 err = depfile_up_to_date_dir(d, st.st_mtime, baselen, path);
2515 closedir(d);
2516 return err;
2517 }
2518
2519 static int is_version_number(const char *version)
2520 {
2521 unsigned int d1, d2;
2522 return (sscanf(version, "%u.%u", &d1, &d2) == 2);
2523 }
2524
2525 static int do_depmod(int argc, char *argv[])
2526 {
2527 FILE *out = NULL;
2528 int err = 0, all = 0, maybe_all = 0, n_config_paths = 0;
2529 char *root = NULL;
2530 const char **config_paths = NULL;
2531 const char *system_map = NULL;
2532 const char *module_symvers = NULL;
2533 const char *null_kmod_config = NULL;
2534 struct utsname un;
2535 struct kmod_ctx *ctx = NULL;
2536 struct cfg cfg;
2537 struct depmod depmod;
2538
2539 memset(&cfg, 0, sizeof(cfg));
2540 memset(&depmod, 0, sizeof(depmod));
2541
2542 for (;;) {
2543 int c, idx = 0;
2544 c = getopt_long(argc, argv, cmdopts_s, cmdopts, &idx);
2545 if (c == -1)
2546 break;
2547 switch (c) {
2548 case 'a':
2549 all = 1;
2550 break;
2551 case 'A':
2552 maybe_all = 1;
2553 break;
2554 case 'b':
2555 root = path_make_absolute_cwd(optarg);
2556 break;
2557 case 'C': {
2558 size_t bytes = sizeof(char *) * (n_config_paths + 2);
2559 void *tmp = realloc(config_paths, bytes);
2560 if (!tmp) {
2561 fputs("Error: out-of-memory\n", stderr);
2562 goto cmdline_failed;
2563 }
2564 config_paths = tmp;
2565 config_paths[n_config_paths] = optarg;
2566 n_config_paths++;
2567 config_paths[n_config_paths] = NULL;
2568 break;
2569 }
2570 case 'E':
2571 module_symvers = optarg;
2572 cfg.check_symvers = 1;
2573 break;
2574 case 'F':
2575 system_map = optarg;
2576 break;
2577 case 'e':
2578 cfg.print_unknown = 1;
2579 break;
2580 case 'v':
2581 verbose++;
2582 break;
2583 case 'n':
2584 out = stdout;
2585 break;
2586 case 'P':
2587 if (optarg[1] != '\0') {
2588 CRIT("-P only takes a single char\n");
2589 goto cmdline_failed;
2590 }
2591 cfg.sym_prefix = optarg[0];
2592 break;
2593 case 'w':
2594 cfg.warn_dups = 1;
2595 break;
2596 case 'u':
2597 case 'q':
2598 case 'r':
2599 case 'm':
2600 if (idx > 0) {
2601 fprintf(stderr,
2602 "ignored deprecated option --%s\n",
2603 cmdopts[idx].name);
2604 } else {
2605 fprintf(stderr,
2606 "ignored deprecated option -%c\n", c);
2607 }
2608 break;
2609 case 'h':
2610 help(basename(argv[0]));
2611 free(config_paths);
2612 return EXIT_SUCCESS;
2613 case 'V':
2614 puts(PACKAGE " version " VERSION);
2615 free(config_paths);
2616 return EXIT_SUCCESS;
2617 case '?':
2618 goto cmdline_failed;
2619 default:
2620 fprintf(stderr,
2621 "Error: unexpected getopt_long() value '%c'.\n",
2622 c);
2623 goto cmdline_failed;
2624 }
2625 }
2626
2627 if (optind < argc && is_version_number(argv[optind])) {
2628 cfg.kversion = argv[optind];
2629 optind++;
2630 } else {
2631 if (uname(&un) < 0) {
2632 CRIT("uname() failed: %s\n", strerror(errno));
2633 goto cmdline_failed;
2634 }
2635 cfg.kversion = un.release;
2636 }
2637
2638 cfg.dirnamelen = snprintf(cfg.dirname, PATH_MAX,
2639 "%s" ROOTPREFIX "/lib/modules/%s",
2640 root == NULL ? "" : root, cfg.kversion);
2641
2642 if (optind == argc)
2643 all = 1;
2644
2645 if (maybe_all) {
2646 if (out == stdout)
2647 goto done;
2648 /* ignore up-to-date errors (< 0) */
2649 if (depfile_up_to_date(cfg.dirname) == 1) {
2650 DBG("%s/modules.dep is up to date!\n", cfg.dirname);
2651 goto done;
2652 }
2653 DBG("%s/modules.dep is outdated, do -a\n", cfg.dirname);
2654 all = 1;
2655 }
2656
2657 ctx = kmod_new(cfg.dirname, &null_kmod_config);
2658 if (ctx == NULL) {
2659 CRIT("kmod_new(\"%s\", {NULL}) failed: %m\n", cfg.dirname);
2660 goto cmdline_failed;
2661 }
2662 kmod_set_log_priority(ctx, verbose);
2663
2664 err = depmod_init(&depmod, &cfg, ctx);
2665 if (err < 0) {
2666 CRIT("depmod_init: %s\n", strerror(-err));
2667 goto depmod_init_failed;
2668 }
2669 ctx = NULL; /* owned by depmod */
2670
2671 if (module_symvers != NULL) {
2672 err = depmod_load_symvers(&depmod, module_symvers);
2673 if (err < 0) {
2674 CRIT("could not load %s: %s\n", module_symvers,
2675 strerror(-err));
2676 goto cmdline_failed;
2677 }
2678 } else if (system_map != NULL) {
2679 err = depmod_load_system_map(&depmod, system_map);
2680 if (err < 0) {
2681 CRIT("could not load %s: %s\n", system_map,
2682 strerror(-err));
2683 goto cmdline_failed;
2684 }
2685 } else if (cfg.print_unknown) {
2686 WRN("-e needs -E or -F\n");
2687 cfg.print_unknown = 0;
2688 }
2689
2690 if (all) {
2691 err = cfg_load(&cfg, config_paths);
2692 if (err < 0) {
2693 CRIT("could not load configuration files\n");
2694 goto cmdline_modules_failed;
2695 }
2696 err = depmod_modules_search(&depmod);
2697 if (err < 0) {
2698 CRIT("could not search modules: %s\n", strerror(-err));
2699 goto cmdline_modules_failed;
2700 }
2701 } else {
2702 int i;
2703
2704 for (i = optind; i < argc; i++) {
2705 const char *path = argv[i];
2706 struct kmod_module *mod;
2707
2708 if (path[0] != '/') {
2709 CRIT("%s: not absolute path.\n", path);
2710 goto cmdline_modules_failed;
2711 }
2712
2713 err = kmod_module_new_from_path(depmod.ctx, path, &mod);
2714 if (err < 0) {
2715 CRIT("could not create module %s: %s\n",
2716 path, strerror(-err));
2717 goto cmdline_modules_failed;
2718 }
2719
2720 err = depmod_module_add(&depmod, mod);
2721 if (err < 0) {
2722 CRIT("could not add module %s: %s\n",
2723 path, strerror(-err));
2724 kmod_module_unref(mod);
2725 goto cmdline_modules_failed;
2726 }
2727 }
2728 }
2729
2730 err = depmod_modules_build_array(&depmod);
2731 if (err < 0) {
2732 CRIT("could not build module array: %s\n",
2733 strerror(-err));
2734 goto cmdline_modules_failed;
2735 }
2736
2737 depmod_modules_sort(&depmod);
2738 err = depmod_load(&depmod);
2739 if (err < 0)
2740 goto cmdline_modules_failed;
2741
2742 err = depmod_output(&depmod, out);
2743
2744 done:
2745 depmod_shutdown(&depmod);
2746 cfg_free(&cfg);
2747 free(config_paths);
2748 return err >= 0 ? EXIT_SUCCESS : EXIT_FAILURE;
2749
2750 cmdline_modules_failed:
2751 depmod_shutdown(&depmod);
2752 depmod_init_failed:
2753 if (ctx != NULL)
2754 kmod_unref(ctx);
2755 cmdline_failed:
2756 cfg_free(&cfg);
2757 free(config_paths);
2758 free(root);
2759 return EXIT_FAILURE;
2760 }
2761
2762 #include "kmod.h"
2763
2764 const struct kmod_cmd kmod_cmd_compat_depmod = {
2765 .name = "depmod",
2766 .cmd = do_depmod,
2767 .help = "compat depmod command",
2768 };