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