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