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