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