]> git.ipfire.org Git - thirdparty/kmod.git/blame - tools/depmod.c
libkmod-module: Simplify kmod_module_insert_module()
[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{
7e0385c4 838 struct dirent *dent;
64b8b586
GSB
839 DIR *d;
840 int err = 0;
841 struct stat st;
842
843 if (stat(path, &st) != 0) {
844 err = -errno;
845 DBG("could not stat '%s': %m\n", path);
846 return err;
847 }
848
849 if (S_ISREG(st.st_mode)) {
850 cfg_files_insert_sorted(p_files, p_n_files, path, NULL);
851 return 0;
c1170883 852 } else if (!S_ISDIR(st.st_mode)) {
64b8b586
GSB
853 ERR("unsupported file mode %s: %#x\n", path, st.st_mode);
854 return -EINVAL;
855 }
856
857 d = opendir(path);
858 if (d == NULL) {
859 ERR("files list %s: %m\n", path);
860 return -EINVAL;
861 }
862
7e0385c4
LDM
863 for (dent = readdir(d); dent != NULL; dent = readdir(d)) {
864 if (cfg_files_filter_out(d, path, dent->d_name))
64b8b586
GSB
865 continue;
866
7e0385c4 867 cfg_files_insert_sorted(p_files, p_n_files, path, dent->d_name);
64b8b586
GSB
868 }
869
870 closedir(d);
035cbdc7 871 DBG("parsed configuration files from %s\n", path);
64b8b586
GSB
872 return err;
873}
874
875static int cfg_load(struct cfg *cfg, const char * const *cfg_paths)
876{
877 size_t i, n_files = 0;
878 struct cfg_file **files = NULL;
879
880 if (cfg_paths == NULL)
881 cfg_paths = default_cfg_paths;
882
883 for (i = 0; cfg_paths[i] != NULL; i++)
884 cfg_files_list(&files, &n_files, cfg_paths[i]);
885
886 for (i = 0; i < n_files; i++) {
887 struct cfg_file *f = files[i];
888 cfg_file_parse(cfg, f->path);
889 cfg_file_free(f);
890 }
891 free(files);
892
893 /* For backward compatibility add "updates" to the head of the search
894 * list here. But only if there was no "search" option specified.
895 */
896 if (cfg->searches == NULL)
897 cfg_search_add(cfg, "updates", 0);
898
899 return 0;
900}
901
902static void cfg_free(struct cfg *cfg)
903{
904 while (cfg->overrides) {
905 struct cfg_override *tmp = cfg->overrides;
906 cfg->overrides = cfg->overrides->next;
907 cfg_override_free(tmp);
908 }
909
910 while (cfg->searches) {
911 struct cfg_search *tmp = cfg->searches;
912 cfg->searches = cfg->searches->next;
913 cfg_search_free(tmp);
914 }
915}
916
917
918/* depmod calculations ***********************************************/
919struct mod {
920 struct kmod_module *kmod;
e4a7352a 921 char *path;
64b8b586 922 const char *relpath; /* path relative to '$ROOT/lib/modules/$VER/' */
b51ac407 923 char *uncrelpath; /* same as relpath but ending in .ko */
7062eca3 924 struct kmod_list *info_list;
ec587f29 925 struct kmod_list *dep_sym_list;
64b8b586
GSB
926 struct array deps; /* struct symbol */
927 size_t baselen; /* points to start of basename/filename */
928 size_t modnamelen;
929 int sort_idx; /* sort index using modules.order */
930 int dep_sort_idx; /* topological sort index */
931 uint16_t idx; /* index in depmod->modules.array */
932 uint16_t users; /* how many modules depend on this one */
933 uint8_t dep_loop : 1;
934 char modname[];
935};
936
937struct symbol {
938 struct mod *owner;
939 uint64_t crc;
940 char name[];
941};
942
943struct depmod {
944 const struct cfg *cfg;
945 struct kmod_ctx *ctx;
946 struct array modules;
88c247f7 947 struct hash *modules_by_uncrelpath;
64b8b586
GSB
948 struct hash *modules_by_name;
949 struct hash *symbols;
950 unsigned int dep_loops;
951};
952
953static void mod_free(struct mod *mod)
954{
955 DBG("free %p kmod=%p, path=%s\n", mod, mod->kmod, mod->path);
956 array_free_array(&mod->deps);
02c64df3 957 kmod_module_unref(mod->kmod);
7062eca3 958 kmod_module_info_free_list(mod->info_list);
ec587f29 959 kmod_module_dependency_symbols_free_list(mod->dep_sym_list);
88c247f7 960 free(mod->uncrelpath);
e4a7352a 961 free(mod->path);
64b8b586
GSB
962 free(mod);
963}
964
965static int mod_add_dependency(struct mod *mod, struct symbol *sym)
966{
967 int err;
968
969 DBG("%s depends on %s %s\n", mod->path, sym->name,
970 sym->owner != NULL ? sym->owner->path : "(unknown)");
971
972 if (sym->owner == NULL)
973 return 0;
974
975 err = array_append_unique(&mod->deps, sym->owner);
976 if (err == -EEXIST)
977 return 0;
978 if (err < 0)
979 return err;
980
981 sym->owner->users++;
982 SHOW("%s needs \"%s\": %s\n", mod->path, sym->name, sym->owner->path);
983 return 0;
984}
985
986static void symbol_free(struct symbol *sym)
987{
988 DBG("free %p sym=%s, owner=%p %s\n", sym, sym->name, sym->owner,
989 sym->owner != NULL ? sym->owner->path : "");
990 free(sym);
991}
992
f6b838e1
LDM
993static int depmod_init(struct depmod *depmod, struct cfg *cfg,
994 struct kmod_ctx *ctx)
64b8b586
GSB
995{
996 int err = 0;
997
998 depmod->cfg = cfg;
999 depmod->ctx = ctx;
1000
1001 array_init(&depmod->modules, 128);
1002
88c247f7
LDM
1003 depmod->modules_by_uncrelpath = hash_new(512, NULL);
1004 if (depmod->modules_by_uncrelpath == NULL) {
64b8b586 1005 err = -errno;
88c247f7 1006 goto modules_by_uncrelpath_failed;
64b8b586
GSB
1007 }
1008
1009 depmod->modules_by_name = hash_new(512, NULL);
1010 if (depmod->modules_by_name == NULL) {
1011 err = -errno;
1012 goto modules_by_name_failed;
1013 }
1014
1015 depmod->symbols = hash_new(2048, (void (*)(void *))symbol_free);
1016 if (depmod->symbols == NULL) {
1017 err = -errno;
1018 goto symbols_failed;
1019 }
1020
1021 return 0;
1022
1023symbols_failed:
1024 hash_free(depmod->modules_by_name);
1025modules_by_name_failed:
88c247f7
LDM
1026 hash_free(depmod->modules_by_uncrelpath);
1027modules_by_uncrelpath_failed:
64b8b586
GSB
1028 return err;
1029}
1030
1031static void depmod_shutdown(struct depmod *depmod)
1032{
1033 size_t i;
1034
1035 hash_free(depmod->symbols);
1036
88c247f7 1037 hash_free(depmod->modules_by_uncrelpath);
64b8b586
GSB
1038
1039 hash_free(depmod->modules_by_name);
1040
1041 for (i = 0; i < depmod->modules.count; i++)
1042 mod_free(depmod->modules.array[i]);
1043 array_free_array(&depmod->modules);
1044
1045 kmod_unref(depmod->ctx);
1046}
1047
1048static int depmod_module_add(struct depmod *depmod, struct kmod_module *kmod)
1049{
1050 const struct cfg *cfg = depmod->cfg;
88c247f7 1051 const char *modname, *lastslash;
64b8b586
GSB
1052 size_t modnamelen;
1053 struct mod *mod;
1054 int err;
1055
1056 modname = kmod_module_get_name(kmod);
1057 modnamelen = strlen(modname) + 1;
1058
1059 mod = calloc(1, sizeof(struct mod) + modnamelen);
1060 if (mod == NULL)
1061 return -ENOMEM;
1062 mod->kmod = kmod;
1063 mod->sort_idx = depmod->modules.count + 1;
1064 mod->dep_sort_idx = INT32_MAX;
64b8b586
GSB
1065 memcpy(mod->modname, modname, modnamelen);
1066 mod->modnamelen = modnamelen;
1067
1068 array_init(&mod->deps, 4);
1069
e4a7352a 1070 mod->path = strdup(kmod_module_get_path(kmod));
88c247f7
LDM
1071 lastslash = strrchr(mod->path, '/');
1072 mod->baselen = lastslash - mod->path;
64b8b586
GSB
1073 if (strncmp(mod->path, cfg->dirname, cfg->dirnamelen) == 0 &&
1074 mod->path[cfg->dirnamelen] == '/')
1075 mod->relpath = mod->path + cfg->dirnamelen + 1;
1076 else
1077 mod->relpath = NULL;
1078
64b8b586
GSB
1079 err = hash_add_unique(depmod->modules_by_name, mod->modname, mod);
1080 if (err < 0) {
1081 ERR("hash_add_unique %s: %s\n", mod->modname, strerror(-err));
88c247f7 1082 goto fail;
64b8b586
GSB
1083 }
1084
1085 if (mod->relpath != NULL) {
88c247f7
LDM
1086 size_t uncrelpathlen = lastslash - mod->relpath + modnamelen
1087 + kmod_exts[KMOD_EXT_UNC].len;
1088 mod->uncrelpath = memdup(mod->relpath, uncrelpathlen + 1);
1089 mod->uncrelpath[uncrelpathlen] = '\0';
1090 err = hash_add_unique(depmod->modules_by_uncrelpath,
1091 mod->uncrelpath, mod);
64b8b586
GSB
1092 if (err < 0) {
1093 ERR("hash_add_unique %s: %s\n",
06294621 1094 mod->uncrelpath, strerror(-err));
64b8b586 1095 hash_del(depmod->modules_by_name, mod->modname);
88c247f7 1096 goto fail;
64b8b586
GSB
1097 }
1098 }
1099
1100 DBG("add %p kmod=%p, path=%s\n", mod, kmod, mod->path);
1101
1102 return 0;
88c247f7
LDM
1103
1104fail:
1105 free(mod->uncrelpath);
1106 free(mod);
1107 return err;
64b8b586
GSB
1108}
1109
3db5bf9d 1110static int depmod_module_del(struct depmod *depmod, struct mod *mod)
64b8b586 1111{
3db5bf9d 1112 DBG("del %p kmod=%p, path=%s\n", mod, mod->kmod, mod->path);
64b8b586 1113
06294621
LDM
1114 if (mod->uncrelpath != NULL)
1115 hash_del(depmod->modules_by_uncrelpath, mod->uncrelpath);
3db5bf9d
GSB
1116
1117 hash_del(depmod->modules_by_name, mod->modname);
1118
3db5bf9d 1119 mod_free(mod);
64b8b586
GSB
1120 return 0;
1121}
1122
1123/* returns if existing module @mod is higher priority than newpath.
1124 * note this is the inverse of module-init-tools is_higher_priority()
1125 */
1126static 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)
1127{
1128 const struct cfg *cfg = depmod->cfg;
1129 const struct cfg_override *ov;
1130 const struct cfg_search *se;
1131 size_t newlen = baselen + modnamelen;
1132 size_t oldlen = mod->baselen + mod->modnamelen;
1133 const char *oldpath = mod->path;
1134 int i, bprio = -1, oldprio = -1, newprio = -1;
1135
026c7b44
GSB
1136 assert(strncmp(newpath, cfg->dirname, cfg->dirnamelen) == 0);
1137 assert(strncmp(oldpath, cfg->dirname, cfg->dirnamelen) == 0);
1138
1139 newpath += cfg->dirnamelen + 1;
1140 newlen -= cfg->dirnamelen + 1;
1141 oldpath += cfg->dirnamelen + 1;
1142 oldlen -= cfg->dirnamelen + 1;
1143
64b8b586
GSB
1144 DBG("comparing priorities of %s and %s\n",
1145 oldpath, newpath);
1146
1147 for (ov = cfg->overrides; ov != NULL; ov = ov->next) {
1148 DBG("override %s\n", ov->path);
1149 if (newlen == ov->len && memcmp(ov->path, newpath, newlen) == 0)
1150 return 0;
1151 if (oldlen == ov->len && memcmp(ov->path, oldpath, oldlen) == 0)
1152 return 1;
1153 }
1154
1155 for (i = 0, se = cfg->searches; se != NULL; se = se->next, i++) {
1156 DBG("search %s\n", se->builtin ? "built-in" : se->path);
1157 if (se->builtin)
1158 bprio = i;
1159 else if (newlen >= se->len &&
1160 memcmp(se->path, newpath, se->len) == 0)
1161 newprio = i;
1162 else if (oldlen >= se->len &&
1163 memcmp(se->path, oldpath, se->len) == 0)
1164 oldprio = i;
1165 }
1166
1167 if (newprio < 0)
1168 newprio = bprio;
1169 if (oldprio < 0)
1170 oldprio = bprio;
1171
1172 DBG("priorities: built-in: %d, old: %d, new: %d\n",
1173 bprio, newprio, oldprio);
1174
1175 return newprio <= oldprio;
1176}
1177
1178static int depmod_modules_search_file(struct depmod *depmod, size_t baselen, size_t namelen, const char *path)
1179{
1180 struct kmod_module *kmod;
1181 struct mod *mod;
3db5bf9d 1182 const char *relpath;
6daceb2f 1183 char modname[PATH_MAX];
64b8b586 1184 size_t modnamelen;
18a492e6 1185 int err;
64b8b586 1186
650f89cd 1187 if (!path_ends_with_kmod_ext(path + baselen, namelen))
64b8b586
GSB
1188 return 0;
1189
3db5bf9d 1190 if (path_to_modname(path, modname, &modnamelen) == NULL) {
63698377 1191 ERR("could not get modname from path %s\n", path);
3db5bf9d 1192 return -EINVAL;
64b8b586
GSB
1193 }
1194
3db5bf9d
GSB
1195 relpath = path + depmod->cfg->dirnamelen + 1;
1196 DBG("try %s (%s)\n", relpath, modname);
1197
64b8b586 1198 mod = hash_find(depmod->modules_by_name, modname);
3db5bf9d
GSB
1199 if (mod == NULL)
1200 goto add;
64b8b586 1201
64b8b586
GSB
1202 if (depmod_module_is_higher_priority(depmod, mod, baselen,
1203 namelen, modnamelen, path)) {
1204 DBG("Ignored lower priority: %s, higher: %s\n",
1205 path, mod->path);
64b8b586
GSB
1206 return 0;
1207 }
1208
3db5bf9d
GSB
1209 DBG("Replace lower priority %s with new module %s\n",
1210 mod->relpath, relpath);
1211 err = depmod_module_del(depmod, mod);
64b8b586 1212 if (err < 0) {
63698377 1213 ERR("could not del module %s: %s\n", mod->path, strerror(-err));
64b8b586
GSB
1214 return err;
1215 }
1216
3db5bf9d
GSB
1217add:
1218 err = kmod_module_new_from_path(depmod->ctx, path, &kmod);
1219 if (err < 0) {
63698377 1220 ERR("could not create module %s: %s\n", path, strerror(-err));
3db5bf9d
GSB
1221 return err;
1222 }
1223
1224 err = depmod_module_add(depmod, kmod);
1225 if (err < 0) {
63698377 1226 ERR("could not add module %s: %s\n",
3db5bf9d
GSB
1227 path, strerror(-err));
1228 kmod_module_unref(kmod);
1229 return err;
1230 }
64b8b586
GSB
1231 return 0;
1232}
1233
1234static int depmod_modules_search_dir(struct depmod *depmod, DIR *d, size_t baselen, char *path)
1235{
1236 struct dirent *de;
1237 int err = 0, dfd = dirfd(d);
1238
1239 while ((de = readdir(d)) != NULL) {
1240 const char *name = de->d_name;
1241 size_t namelen;
1242 uint8_t is_dir;
1243
1244 if (name[0] == '.' && (name[1] == '\0' ||
1245 (name[1] == '.' && name[2] == '\0')))
1246 continue;
1247 if (streq(name, "build") || streq(name, "source"))
1248 continue;
1249 namelen = strlen(name);
1250 if (baselen + namelen + 2 >= PATH_MAX) {
1251 path[baselen] = '\0';
1958af88 1252 ERR("path is too long %s%s\n", path, name);
64b8b586
GSB
1253 continue;
1254 }
1255 memcpy(path + baselen, name, namelen + 1);
1256
1257 if (de->d_type == DT_REG)
1258 is_dir = 0;
1259 else if (de->d_type == DT_DIR)
1260 is_dir = 1;
1261 else {
1262 struct stat st;
1263 if (fstatat(dfd, name, &st, 0) < 0) {
1264 ERR("fstatat(%d, %s): %m\n", dfd, name);
1265 continue;
1266 } else if (S_ISREG(st.st_mode))
1267 is_dir = 0;
1268 else if (S_ISDIR(st.st_mode))
1269 is_dir = 1;
1270 else {
1271 ERR("unsupported file type %s: %o\n",
1272 path, st.st_mode & S_IFMT);
1273 continue;
1274 }
1275 }
1276
1277 if (is_dir) {
1278 int fd;
1279 DIR *subdir;
1280 if (baselen + namelen + 2 + NAME_MAX >= PATH_MAX) {
1281 ERR("directory path is too long %s\n", path);
1282 continue;
1283 }
1284 fd = openat(dfd, name, O_RDONLY);
1285 if (fd < 0) {
1286 ERR("openat(%d, %s, O_RDONLY): %m\n",
1287 dfd, name);
1288 continue;
1289 }
1290 subdir = fdopendir(fd);
1291 if (subdir == NULL) {
1292 ERR("fdopendir(%d): %m\n", fd);
1293 close(fd);
1294 continue;
1295 }
1296 path[baselen + namelen] = '/';
1297 path[baselen + namelen + 1] = '\0';
1298 err = depmod_modules_search_dir(depmod, subdir,
1299 baselen + namelen + 1,
1300 path);
1301 closedir(subdir);
1302 } else {
1303 err = depmod_modules_search_file(depmod, baselen,
1304 namelen, path);
1305 }
1306
1307 if (err < 0) {
1308 path[baselen + namelen] = '\0';
1309 ERR("failed %s: %s\n", path, strerror(-err));
1310 err = 0; /* ignore errors */
1311 }
1312 }
1313
1314 return err;
1315}
1316
1317static int depmod_modules_search(struct depmod *depmod)
1318{
1319 char path[PATH_MAX];
1320 DIR *d = opendir(depmod->cfg->dirname);
1321 size_t baselen;
1322 int err;
1323 if (d == NULL) {
1324 err = -errno;
63698377 1325 ERR("could not open directory %s: %m\n", depmod->cfg->dirname);
64b8b586
GSB
1326 return err;
1327 }
1328
1329 baselen = depmod->cfg->dirnamelen;
1330 memcpy(path, depmod->cfg->dirname, baselen);
1331 path[baselen] = '/';
1332 baselen++;
1333 path[baselen] = '\0';
1334
1335 err = depmod_modules_search_dir(depmod, d, baselen, path);
1336 closedir(d);
20c6e18c 1337 return err;
64b8b586
GSB
1338}
1339
1340static int mod_cmp(const void *pa, const void *pb) {
1341 const struct mod *a = *(const struct mod **)pa;
1342 const struct mod *b = *(const struct mod **)pb;
1343 if (a->dep_loop == b->dep_loop)
1344 return a->sort_idx - b->sort_idx;
1345 else if (a->dep_loop)
1346 return 1;
1347 else if (b->dep_loop)
1348 return -1;
1349 return a->sort_idx - b->sort_idx;
1350}
1351
00bd3191
JAS
1352static int depmod_modules_build_array(struct depmod *depmod)
1353{
1354 struct hash_iter module_iter;
33557e8d 1355 const void *v;
00bd3191
JAS
1356 int err;
1357
1358 hash_iter_init(depmod->modules_by_name, &module_iter);
33557e8d
LDM
1359 while (hash_iter_next(&module_iter, NULL, &v)) {
1360 struct mod *mod = (struct mod *) v;
1361 mod->idx = depmod->modules.count;
00bd3191
JAS
1362 err = array_append(&depmod->modules, mod);
1363 if (err < 0)
1364 return err;
1365 }
1366
1367 return 0;
1368}
1369
64b8b586
GSB
1370static void depmod_modules_sort(struct depmod *depmod)
1371{
1372 char order_file[PATH_MAX], line[PATH_MAX];
1373 FILE *fp;
1374 unsigned idx = 0, total = 0;
1375
1376 snprintf(order_file, sizeof(order_file), "%s/modules.order",
1377 depmod->cfg->dirname);
1378 fp = fopen(order_file, "r");
1379 if (fp == NULL) {
56406fdb 1380 WRN("could not open %s: %m\n", order_file);
64b8b586
GSB
1381 return;
1382 }
1383
1384 while (fgets(line, sizeof(line), fp) != NULL) {
1385 size_t len = strlen(line);
1386 idx++;
1387 if (len == 0)
1388 continue;
1389 if (line[len - 1] != '\n') {
1390 ERR("%s:%u corrupted line misses '\\n'\n",
1391 order_file, idx);
1392 goto corrupted;
1393 }
1394 }
1395 total = idx + 1;
1396 idx = 0;
1397 fseek(fp, 0, SEEK_SET);
1398 while (fgets(line, sizeof(line), fp) != NULL) {
1399 size_t len = strlen(line);
1400 struct mod *mod;
1401
1402 idx++;
1403 if (len == 0)
1404 continue;
1405 line[len - 1] = '\0';
1406
88c247f7 1407 mod = hash_find(depmod->modules_by_uncrelpath, line);
64b8b586
GSB
1408 if (mod == NULL)
1409 continue;
1410 mod->sort_idx = idx - total;
1411 }
1412
1413 array_sort(&depmod->modules, mod_cmp);
1414 for (idx = 0; idx < depmod->modules.count; idx++) {
1415 struct mod *m = depmod->modules.array[idx];
1416 m->idx = idx;
1417 }
1418
1419corrupted:
1420 fclose(fp);
1421}
1422
f6b838e1 1423static int depmod_symbol_add(struct depmod *depmod, const char *name,
572a2711
AM
1424 bool prefix_skipped, uint64_t crc,
1425 const struct mod *owner)
64b8b586
GSB
1426{
1427 size_t namelen;
1428 int err;
1429 struct symbol *sym;
1430
572a2711 1431 if (!prefix_skipped && (name[0] == depmod->cfg->sym_prefix))
64b8b586
GSB
1432 name++;
1433
1434 namelen = strlen(name) + 1;
1435 sym = malloc(sizeof(struct symbol) + namelen);
1436 if (sym == NULL)
1437 return -ENOMEM;
1438
1439 sym->owner = (struct mod *)owner;
1440 sym->crc = crc;
1441 memcpy(sym->name, name, namelen);
1442
1443 err = hash_add(depmod->symbols, sym->name, sym);
1444 if (err < 0) {
1445 free(sym);
1446 return err;
1447 }
1448
1449 DBG("add %p sym=%s, owner=%p %s\n", sym, sym->name, owner,
1450 owner != NULL ? owner->path : "");
1451
1452 return 0;
1453}
1454
f6b838e1
LDM
1455static struct symbol *depmod_symbol_find(const struct depmod *depmod,
1456 const char *name)
64b8b586
GSB
1457{
1458 if (name[0] == '.') /* PPC64 needs this: .foo == foo */
1459 name++;
1460 if (name[0] == depmod->cfg->sym_prefix)
1461 name++;
1462 return hash_find(depmod->symbols, name);
1463}
1464
ec587f29 1465static int depmod_load_modules(struct depmod *depmod)
64b8b586 1466{
7062eca3 1467 struct mod **itr, **itr_end;
64b8b586
GSB
1468
1469 DBG("load symbols (%zd modules)\n", depmod->modules.count);
1470
7062eca3 1471 itr = (struct mod **)depmod->modules.array;
64b8b586
GSB
1472 itr_end = itr + depmod->modules.count;
1473 for (; itr < itr_end; itr++) {
7062eca3 1474 struct mod *mod = *itr;
64b8b586
GSB
1475 struct kmod_list *l, *list = NULL;
1476 int err = kmod_module_get_symbols(mod->kmod, &list);
1477 if (err < 0) {
819f79a2
DR
1478 if (err == -ENOENT)
1479 DBG("ignoring %s: no symbols\n", mod->path);
1480 else
1481 ERR("failed to load symbols from %s: %s\n",
1482 mod->path, strerror(-err));
7062eca3 1483 goto load_info;
64b8b586
GSB
1484 }
1485 kmod_list_foreach(l, list) {
1486 const char *name = kmod_module_symbol_get_symbol(l);
1487 uint64_t crc = kmod_module_symbol_get_crc(l);
572a2711 1488 depmod_symbol_add(depmod, name, false, crc, mod);
64b8b586
GSB
1489 }
1490 kmod_module_symbols_free_list(list);
7062eca3
LDM
1491
1492load_info:
1493 kmod_module_get_info(mod->kmod, &mod->info_list);
ec587f29
LDM
1494 kmod_module_get_dependency_symbols(mod->kmod,
1495 &mod->dep_sym_list);
e4a7352a
LDM
1496 kmod_module_unref(mod->kmod);
1497 mod->kmod = NULL;
64b8b586
GSB
1498 }
1499
1958af88 1500 DBG("loaded symbols (%zd modules, %u symbols)\n",
64b8b586
GSB
1501 depmod->modules.count, hash_get_count(depmod->symbols));
1502
1503 return 0;
1504}
1505
1506static int depmod_load_module_dependencies(struct depmod *depmod, struct mod *mod)
1507{
1508 const struct cfg *cfg = depmod->cfg;
ec587f29 1509 struct kmod_list *l;
64b8b586
GSB
1510
1511 DBG("do dependencies of %s\n", mod->path);
ec587f29 1512 kmod_list_foreach(l, mod->dep_sym_list) {
64b8b586
GSB
1513 const char *name = kmod_module_dependency_symbol_get_symbol(l);
1514 uint64_t crc = kmod_module_dependency_symbol_get_crc(l);
0de40463 1515 int bindtype = kmod_module_dependency_symbol_get_bind(l);
64b8b586 1516 struct symbol *sym = depmod_symbol_find(depmod, name);
0de40463 1517 uint8_t is_weak = bindtype == KMOD_SYMBOL_WEAK;
64b8b586
GSB
1518
1519 if (sym == NULL) {
1520 DBG("%s needs (%c) unknown symbol %s\n",
0de40463 1521 mod->path, bindtype, name);
64b8b586
GSB
1522 if (cfg->print_unknown && !is_weak)
1523 WRN("%s needs unknown symbol %s\n",
1524 mod->path, name);
1525 continue;
1526 }
1527
1528 if (cfg->check_symvers && sym->crc != crc && !is_weak) {
1529 DBG("symbol %s (%#"PRIx64") module %s (%#"PRIx64")\n",
1530 sym->name, sym->crc, mod->path, crc);
1531 if (cfg->print_unknown)
1532 WRN("%s disagrees about version of symbol %s\n",
1533 mod->path, name);
1534 }
1535
1536 mod_add_dependency(mod, sym);
1537 }
ec587f29 1538
64b8b586
GSB
1539 return 0;
1540}
1541
1542static int depmod_load_dependencies(struct depmod *depmod)
1543{
1544 struct mod **itr, **itr_end;
1545
1958af88 1546 DBG("load dependencies (%zd modules, %u symbols)\n",
64b8b586
GSB
1547 depmod->modules.count, hash_get_count(depmod->symbols));
1548
1549 itr = (struct mod **)depmod->modules.array;
1550 itr_end = itr + depmod->modules.count;
1551 for (; itr < itr_end; itr++) {
1552 struct mod *mod = *itr;
ec587f29
LDM
1553
1554 if (mod->dep_sym_list == NULL) {
1555 DBG("ignoring %s: no dependency symbols\n", mod->path);
1556 continue;
1557 }
1558
64b8b586
GSB
1559 depmod_load_module_dependencies(depmod, mod);
1560 }
1561
1958af88 1562 DBG("loaded dependencies (%zd modules, %u symbols)\n",
64b8b586
GSB
1563 depmod->modules.count, hash_get_count(depmod->symbols));
1564
1565 return 0;
1566}
1567
1568static int dep_cmp(const void *pa, const void *pb)
1569{
1570 const struct mod *a = *(const struct mod **)pa;
1571 const struct mod *b = *(const struct mod **)pb;
1572 if (a->dep_loop == b->dep_loop)
1573 return a->dep_sort_idx - b->dep_sort_idx;
1574 else if (a->dep_loop)
1575 return 1;
1576 else if (b->dep_loop)
1577 return -1;
1578 return a->dep_sort_idx - b->dep_sort_idx;
1579}
1580
1581static void depmod_sort_dependencies(struct depmod *depmod)
1582{
1583 struct mod **itr, **itr_end;
1584 itr = (struct mod **)depmod->modules.array;
1585 itr_end = itr + depmod->modules.count;
1586 for (; itr < itr_end; itr++) {
1587 struct mod *m = *itr;
1588 if (m->deps.count > 1)
1589 array_sort(&m->deps, dep_cmp);
1590 }
1591}
1592
1593static int depmod_calculate_dependencies(struct depmod *depmod)
1594{
1595 const struct mod **itrm;
1596 uint16_t *users, *roots, *sorted;
1597 uint16_t i, n_roots = 0, n_sorted = 0, n_mods = depmod->modules.count;
1598
1599 users = malloc(sizeof(uint16_t) * n_mods * 3);
1600 if (users == NULL)
1601 return -ENOMEM;
1602 roots = users + n_mods;
1603 sorted = roots + n_mods;
1604
1958af88 1605 DBG("calculate dependencies and ordering (%hu modules)\n", n_mods);
64b8b586
GSB
1606
1607 assert(depmod->modules.count < UINT16_MAX);
1608
1609 /* populate modules users (how many modules uses it) */
1610 itrm = (const struct mod **)depmod->modules.array;
1611 for (i = 0; i < n_mods; i++, itrm++) {
1612 const struct mod *m = *itrm;
1613 users[i] = m->users;
1614 if (users[i] == 0) {
1615 roots[n_roots] = i;
1616 n_roots++;
1617 }
1618 }
1619
1620 /* topological sort (outputs modules without users first) */
1621 while (n_roots > 0) {
1622 const struct mod **itr_dst, **itr_dst_end;
1623 struct mod *src;
1624 uint16_t src_idx = roots[--n_roots];
1625
1626 src = depmod->modules.array[src_idx];
1627 src->dep_sort_idx = n_sorted;
1628 sorted[n_sorted] = src_idx;
1629 n_sorted++;
1630
1631 itr_dst = (const struct mod **)src->deps.array;
1632 itr_dst_end = itr_dst + src->deps.count;
1633 for (; itr_dst < itr_dst_end; itr_dst++) {
1634 const struct mod *dst = *itr_dst;
1635 uint16_t dst_idx = dst->idx;
1636 assert(users[dst_idx] > 0);
1637 users[dst_idx]--;
1638 if (users[dst_idx] == 0) {
1639 roots[n_roots] = dst_idx;
1640 n_roots++;
1641 }
1642 }
1643 }
1644
1645 if (n_sorted < n_mods) {
1958af88 1646 WRN("found %u modules in dependency cycles!\n",
64b8b586
GSB
1647 n_mods - n_sorted);
1648 for (i = 0; i < n_mods; i++) {
1649 struct mod *m;
1650 if (users[i] == 0)
1651 continue;
1652 m = depmod->modules.array[i];
1653 WRN("%s in dependency cycle!\n", m->path);
1654 m->dep_loop = 1;
1655 m->dep_sort_idx = INT32_MAX;
1656 depmod->dep_loops++;
1657 }
1658 }
1659
1660 depmod_sort_dependencies(depmod);
1661
1958af88 1662 DBG("calculated dependencies and ordering (%u loops, %hu modules)\n",
64b8b586
GSB
1663 depmod->dep_loops, n_mods);
1664
1665 free(users);
1666 return 0;
1667}
1668
1669static int depmod_load(struct depmod *depmod)
1670{
1671 int err;
1672
ec587f29 1673 err = depmod_load_modules(depmod);
64b8b586
GSB
1674 if (err < 0)
1675 return err;
1676
1677 err = depmod_load_dependencies(depmod);
1678 if (err < 0)
1679 return err;
1680
1681 err = depmod_calculate_dependencies(depmod);
1682 if (err < 0)
1683 return err;
1684
1685 return 0;
1686}
1687
8e3505c5
GSB
1688static size_t mod_count_all_dependencies(const struct mod *mod)
1689{
1690 size_t i, count = 0;
1691 for (i = 0; i < mod->deps.count; i++) {
1692 const struct mod *d = mod->deps.array[i];
1693 count += 1 + mod_count_all_dependencies(d);
1694 }
1695 return count;
1696}
1697
1698static int mod_fill_all_unique_dependencies(const struct mod *mod, const struct mod **deps, size_t n_deps, size_t *last)
1699{
1700 size_t i;
1701 int err = 0;
1702 for (i = 0; i < mod->deps.count; i++) {
1703 const struct mod *d = mod->deps.array[i];
1704 size_t j;
1705 uint8_t exists = 0;
1706
1707 for (j = 0; j < *last; j++) {
1708 if (deps[j] == d) {
1709 exists = 1;
1710 break;
1711 }
1712 }
1713
1714 if (exists)
1715 continue;
1716
1717 if (*last >= n_deps)
1718 return -ENOSPC;
1719 deps[*last] = d;
1720 (*last)++;
1721 err = mod_fill_all_unique_dependencies(d, deps, n_deps, last);
1722 if (err < 0)
1723 break;
1724 }
1725 return err;
1726}
1727
1728static const struct mod **mod_get_all_sorted_dependencies(const struct mod *mod, size_t *n_deps)
1729{
1730 const struct mod **deps;
1731 size_t last = 0;
1732
1733 *n_deps = mod_count_all_dependencies(mod);
1734 if (*n_deps == 0)
1735 return NULL;
1736
1737 deps = malloc(sizeof(struct mod *) * (*n_deps));
1738 if (deps == NULL)
1739 return NULL;
1740
1741 if (mod_fill_all_unique_dependencies(mod, deps, *n_deps, &last) < 0) {
1742 free(deps);
1743 return NULL;
1744 }
1745
1746 qsort(deps, last, sizeof(struct mod *), dep_cmp);
1747 *n_deps = last;
1748 return deps;
1749}
1750
1751static inline const char *mod_get_compressed_path(const struct mod *mod)
1752{
1753 if (mod->relpath != NULL)
1754 return mod->relpath;
1755 return mod->path;
1756}
1757
1758static int output_deps(struct depmod *depmod, FILE *out)
1759{
1760 size_t i;
1761
1762 for (i = 0; i < depmod->modules.count; i++) {
1763 const struct mod **deps, *mod = depmod->modules.array[i];
1764 const char *p = mod_get_compressed_path(mod);
1765 size_t j, n_deps;
1766
1767 if (mod->dep_loop) {
1768 DBG("Ignored %s due dependency loops\n", p);
1769 continue;
1770 }
1771
1772 fprintf(out, "%s:", p);
1773
1774 if (mod->deps.count == 0)
1775 goto end;
1776
1777 deps = mod_get_all_sorted_dependencies(mod, &n_deps);
1778 if (deps == NULL) {
63698377 1779 ERR("could not get all sorted dependencies of %s\n", p);
8e3505c5
GSB
1780 goto end;
1781 }
1782
1783 for (j = 0; j < n_deps; j++) {
1784 const struct mod *d = deps[j];
1785 if (d->dep_loop) {
1786 DBG("Ignored %s (dependency of %s) "
1787 "due dependency loops\n",
1788 mod_get_compressed_path(d), p);
1789 continue;
1790 }
1791 fprintf(out, " %s", mod_get_compressed_path(d));
1792 }
1793 free(deps);
1794 end:
1795 putc('\n', out);
1796 }
1797
1798 return 0;
1799}
1800
7436788c
GSB
1801static int output_deps_bin(struct depmod *depmod, FILE *out)
1802{
1803 struct index_node *idx;
1804 size_t i;
1805
1806 if (out == stdout)
1807 return 0;
1808
1809 idx = index_create();
1810 if (idx == NULL)
1811 return -ENOMEM;
1812
1813 for (i = 0; i < depmod->modules.count; i++) {
1814 const struct mod **deps, *mod = depmod->modules.array[i];
1815 const char *p = mod_get_compressed_path(mod);
1816 char *line;
1817 size_t j, n_deps, linepos, linelen, slen;
1818 int duplicate;
1819
1820 if (mod->dep_loop) {
1821 DBG("Ignored %s due dependency loops\n", p);
1822 continue;
1823 }
1824
1825 deps = mod_get_all_sorted_dependencies(mod, &n_deps);
1826 if (deps == NULL && n_deps > 0) {
63698377 1827 ERR("could not get all sorted dependencies of %s\n", p);
7436788c
GSB
1828 continue;
1829 }
1830
1831 linelen = strlen(p) + 1;
1832 for (j = 0; j < n_deps; j++) {
1833 const struct mod *d = deps[j];
1834 if (d->dep_loop) {
1835 DBG("Ignored %s (dependency of %s) "
1836 "due dependency loops\n",
1837 mod_get_compressed_path(d), p);
1838 continue;
1839 }
1840 linelen += 1 + strlen(mod_get_compressed_path(d));
1841 }
1842
1843 line = malloc(linelen + 1);
1844 if (line == NULL) {
1845 free(deps);
1846 ERR("modules.deps.bin: out of memory\n");
1847 continue;
1848 }
1849
1850 linepos = 0;
1851 slen = strlen(p);
1852 memcpy(line + linepos, p, slen);
1853 linepos += slen;
1854 line[linepos] = ':';
1855 linepos++;
1856
1857 for (j = 0; j < n_deps; j++) {
1858 const struct mod *d = deps[j];
1859 const char *dp;
1860 if (d->dep_loop)
1861 continue;
1862 line[linepos] = ' ';
1863 linepos++;
1864
1865 dp = mod_get_compressed_path(d);
1866 slen = strlen(dp);
1867 memcpy(line + linepos, dp, slen);
1868 linepos += slen;
1869 }
1870 line[linepos] = '\0';
1871
1872 duplicate = index_insert(idx, mod->modname, line, mod->idx);
1873 if (duplicate && depmod->cfg->warn_dups)
1874 WRN("duplicate module deps:\n%s\n", line);
1875 free(line);
ea1b8c37 1876 free(deps);
7436788c
GSB
1877 }
1878
1879 index_write(idx, out);
1880 index_destroy(idx);
1881
1882 return 0;
1883}
1884
0d131745
GSB
1885static int output_aliases(struct depmod *depmod, FILE *out)
1886{
1887 size_t i;
1888
1889 fputs("# Aliases extracted from modules themselves.\n", out);
1890
1891 for (i = 0; i < depmod->modules.count; i++) {
1892 const struct mod *mod = depmod->modules.array[i];
7062eca3
LDM
1893 struct kmod_list *l;
1894
1895 kmod_list_foreach(l, mod->info_list) {
0d131745
GSB
1896 const char *key = kmod_module_info_get_key(l);
1897 const char *value = kmod_module_info_get_value(l);
1898
1899 if (!streq(key, "alias"))
1900 continue;
1901
447eed8c 1902 fprintf(out, "alias %s %s\n", value, mod->modname);
0d131745 1903 }
0d131745
GSB
1904 }
1905
1906 return 0;
1907}
1908
ec77abb9
GSB
1909static int output_aliases_bin(struct depmod *depmod, FILE *out)
1910{
1911 char buf[1024];
1912 struct index_node *idx;
1913 size_t i;
1914
1915 if (out == stdout)
1916 return 0;
1917
1918 idx = index_create();
1919 if (idx == NULL)
1920 return -ENOMEM;
1921
1922 for (i = 0; i < depmod->modules.count; i++) {
1923 const struct mod *mod = depmod->modules.array[i];
7062eca3
LDM
1924 struct kmod_list *l;
1925
1926 kmod_list_foreach(l, mod->info_list) {
ec77abb9
GSB
1927 const char *key = kmod_module_info_get_key(l);
1928 const char *value = kmod_module_info_get_value(l);
447eed8c 1929 const char *alias;
ec77abb9
GSB
1930 int duplicate;
1931
1932 if (!streq(key, "alias"))
1933 continue;
1934
0c010fae 1935 alias = underscores2(value, buf, sizeof(buf));
ec77abb9
GSB
1936 if (alias == NULL)
1937 continue;
1938
447eed8c 1939 duplicate = index_insert(idx, alias, mod->modname,
ec77abb9
GSB
1940 mod->idx);
1941 if (duplicate && depmod->cfg->warn_dups)
1942 WRN("duplicate module alias:\n%s %s\n",
447eed8c 1943 alias, mod->modname);
ec77abb9 1944 }
ec77abb9
GSB
1945 }
1946
1947 index_write(idx, out);
1948 index_destroy(idx);
1949
1950 return 0;
1951}
1952
8bc830ef
GSB
1953static int output_softdeps(struct depmod *depmod, FILE *out)
1954{
1955 size_t i;
1956
1957 fputs("# Soft dependencies extracted from modules themselves.\n", out);
1958 fputs("# Copy, with a .conf extension, to /etc/modprobe.d to use "
1959 "it with modprobe.\n", out);
1960
1961 for (i = 0; i < depmod->modules.count; i++) {
1962 const struct mod *mod = depmod->modules.array[i];
7062eca3
LDM
1963 struct kmod_list *l;
1964
1965 kmod_list_foreach(l, mod->info_list) {
8bc830ef
GSB
1966 const char *key = kmod_module_info_get_key(l);
1967 const char *value = kmod_module_info_get_value(l);
1968
1969 if (!streq(key, "softdep"))
1970 continue;
1971
447eed8c 1972 fprintf(out, "softdep %s %s\n", mod->modname, value);
8bc830ef 1973 }
8bc830ef
GSB
1974 }
1975
1976 return 0;
1977}
1978
9a14d0e9
GSB
1979static int output_symbols(struct depmod *depmod, FILE *out)
1980{
5cd13064 1981 struct hash_iter iter;
55021bed 1982 const void *v;
9a14d0e9
GSB
1983
1984 fputs("# Aliases for symbols, used by symbol_request().\n", out);
1985
5cd13064
LDM
1986 hash_iter_init(depmod->symbols, &iter);
1987
55021bed
REB
1988 while (hash_iter_next(&iter, NULL, &v)) {
1989 const struct symbol *sym = v;
5cd13064
LDM
1990 if (sym->owner == NULL)
1991 continue;
1992
1993 fprintf(out, "alias symbol:%s %s\n",
1994 sym->name, sym->owner->modname);
9a14d0e9
GSB
1995 }
1996
1997 return 0;
1998}
1999
75a9723b
GSB
2000static int output_symbols_bin(struct depmod *depmod, FILE *out)
2001{
2002 struct index_node *idx;
2003 char alias[1024];
5cd13064
LDM
2004 size_t baselen = sizeof("symbol:") - 1;
2005 struct hash_iter iter;
55021bed 2006 const void *v;
75a9723b
GSB
2007
2008 if (out == stdout)
2009 return 0;
2010
2011 idx = index_create();
2012 if (idx == NULL)
2013 return -ENOMEM;
2014
2015 memcpy(alias, "symbol:", baselen);
5cd13064 2016 hash_iter_init(depmod->symbols, &iter);
75a9723b 2017
55021bed 2018 while (hash_iter_next(&iter, NULL, &v)) {
5cd13064 2019 int duplicate;
55021bed 2020 const struct symbol *sym = v;
75a9723b 2021
5cd13064
LDM
2022 if (sym->owner == NULL)
2023 continue;
75a9723b 2024
5cd13064
LDM
2025 strcpy(alias + baselen, sym->name);
2026 duplicate = index_insert(idx, alias, sym->owner->modname,
2027 sym->owner->idx);
2028
2029 if (duplicate && depmod->cfg->warn_dups)
2030 WRN("duplicate module syms:\n%s %s\n",
2031 alias, sym->owner->modname);
75a9723b
GSB
2032 }
2033
2034 index_write(idx, out);
2035 index_destroy(idx);
5cd13064 2036
75a9723b
GSB
2037 return 0;
2038}
2039
4b144e5f
GSB
2040static int output_builtin_bin(struct depmod *depmod, FILE *out)
2041{
2042 FILE *in;
2043 struct index_node *idx;
6daceb2f 2044 char infile[PATH_MAX], line[PATH_MAX], modname[PATH_MAX];
4b144e5f
GSB
2045
2046 if (out == stdout)
2047 return 0;
2048
2049 snprintf(infile, sizeof(infile), "%s/modules.builtin",
c5db1a3f 2050 depmod->cfg->dirname);
4b144e5f
GSB
2051 in = fopen(infile, "r");
2052 if (in == NULL) {
56406fdb 2053 WRN("could not open %s: %m\n", infile);
c5db1a3f 2054 return 0;
4b144e5f
GSB
2055 }
2056
2057 idx = index_create();
2058 if (idx == NULL) {
2059 fclose(in);
2060 return -ENOMEM;
2061 }
2062
2063 while (fgets(line, sizeof(line), in) != NULL) {
2064 if (!isalpha(line[0])) {
2065 ERR("Invalid modules.builtin line: %s\n", line);
2066 continue;
2067 }
2068
2069 path_to_modname(line, modname, NULL);
2070 index_insert(idx, modname, "", 0);
2071 }
2072
2073 index_write(idx, out);
2074 index_destroy(idx);
2075 fclose(in);
2076
2077 return 0;
2078}
2079
25c41512
GSB
2080static int output_devname(struct depmod *depmod, FILE *out)
2081{
2082 size_t i;
2083
2084 fputs("# Device nodes to trigger on-demand module loading.\n", out);
2085
2086 for (i = 0; i < depmod->modules.count; i++) {
2087 const struct mod *mod = depmod->modules.array[i];
7062eca3 2088 struct kmod_list *l;
25c41512
GSB
2089 const char *devname = NULL;
2090 char type = '\0';
2091 unsigned int major = 0, minor = 0;
25c41512 2092
7062eca3 2093 kmod_list_foreach(l, mod->info_list) {
25c41512
GSB
2094 const char *key = kmod_module_info_get_key(l);
2095 const char *value = kmod_module_info_get_value(l);
2096 unsigned int maj, min;
2097
2098 if (!streq(key, "alias"))
2099 continue;
2100
2101 if (strstartswith(value, "devname:"))
2102 devname = value + sizeof("devname:") - 1;
2103 else if (sscanf(value, "char-major-%u-%u",
2104 &maj, &min) == 2) {
2105 type = 'c';
2106 major = maj;
2107 minor = min;
2108 } else if (sscanf(value, "block-major-%u-%u",
2109 &maj, &min) == 2) {
2110 type = 'b';
2111 major = maj;
2112 minor = min;
2113 }
2114
6506ddf5
TG
2115 if (type != '\0' && devname != NULL)
2116 break;
2117 }
2118
2119 if (devname != NULL) {
2120 if (type != '\0')
447eed8c 2121 fprintf(out, "%s %s %c%u:%u\n", mod->modname,
25c41512 2122 devname, type, major, minor);
6506ddf5
TG
2123 else
2124 ERR("Module '%s' has devname (%s) but "
2125 "lacks major and minor information. "
2126 "Ignoring.\n", mod->modname, devname);
25c41512 2127 }
25c41512
GSB
2128 }
2129
2130 return 0;
2131}
2132
2133static int depmod_output(struct depmod *depmod, FILE *out)
2134{
2135 static const struct depfile {
2136 const char *name;
2137 int (*cb)(struct depmod *depmod, FILE *out);
2138 } *itr, depfiles[] = {
015946da
LDM
2139 { "modules.dep", output_deps },
2140 { "modules.dep.bin", output_deps_bin },
2141 { "modules.alias", output_aliases },
2142 { "modules.alias.bin", output_aliases_bin },
2143 { "modules.softdep", output_softdeps },
2144 { "modules.symbols", output_symbols },
2145 { "modules.symbols.bin", output_symbols_bin },
2146 { "modules.builtin.bin", output_builtin_bin },
2147 { "modules.devname", output_devname },
2148 { }
25c41512
GSB
2149 };
2150 const char *dname = depmod->cfg->dirname;
2151 int dfd, err = 0;
2152
2153 if (out != NULL)
2154 dfd = -1;
2155 else {
2156 dfd = open(dname, O_RDONLY);
2157 if (dfd < 0) {
2158 err = -errno;
63698377 2159 CRIT("could not open directory %s: %m\n", dname);
25c41512
GSB
2160 return err;
2161 }
2162 }
2163
2164 for (itr = depfiles; itr->name != NULL; itr++) {
2165 FILE *fp = out;
2166 char tmp[NAME_MAX] = "";
3f376cd8 2167 int r, ferr;
25c41512
GSB
2168
2169 if (fp == NULL) {
2170 int flags = O_CREAT | O_TRUNC | O_WRONLY;
2171 int mode = 0644;
2172 int fd;
2173
2174 snprintf(tmp, sizeof(tmp), "%s.tmp", itr->name);
2175 fd = openat(dfd, tmp, flags, mode);
2176 if (fd < 0) {
2177 ERR("openat(%s, %s, %o, %o): %m\n",
2178 dname, tmp, flags, mode);
2179 continue;
2180 }
2181 fp = fdopen(fd, "wb");
2182 if (fp == NULL) {
2183 ERR("fdopen(%d=%s/%s): %m\n", fd, dname, tmp);
2184 close(fd);
2185 continue;
2186 }
2187 }
2188
2189 r = itr->cb(depmod, fp);
2190 if (fp == out)
2191 continue;
2192
3f376cd8
LDM
2193 ferr = ferror(fp) | fclose(fp);
2194
25c41512
GSB
2195 if (r < 0) {
2196 if (unlinkat(dfd, tmp, 0) != 0)
2197 ERR("unlinkat(%s, %s): %m\n", dname, tmp);
80e49ad9
LDM
2198
2199 ERR("Could not write index '%s': %s\n", itr->name,
2200 strerror(-r));
2201 err = -errno;
2202 break;
2203 }
2204
2205 unlinkat(dfd, itr->name, 0);
2206 if (renameat(dfd, tmp, dfd, itr->name) != 0) {
2207 err = -errno;
2208 CRIT("renameat(%s, %s, %s, %s): %m\n",
2209 dname, tmp, dname, itr->name);
2210 break;
25c41512 2211 }
a4fb97a7 2212
3f376cd8 2213 if (ferr) {
a4fb97a7 2214 err = -ENOSPC;
3f376cd8
LDM
2215 ERR("Could not create index '%s'. Output is truncated: %s\n",
2216 itr->name, strerror(-err));
a4fb97a7
LDM
2217 break;
2218 }
25c41512
GSB
2219 }
2220
2221 if (dfd >= 0)
2222 close(dfd);
80e49ad9 2223
25c41512
GSB
2224 return err;
2225}
2226
4a0e46da
GSB
2227static void depmod_add_fake_syms(struct depmod *depmod)
2228{
2229 /* __this_module is magic inserted by kernel loader. */
572a2711 2230 depmod_symbol_add(depmod, "__this_module", true, 0, NULL);
4a0e46da 2231 /* On S390, this is faked up too */
572a2711 2232 depmod_symbol_add(depmod, "_GLOBAL_OFFSET_TABLE_", true, 0, NULL);
4a0e46da
GSB
2233}
2234
2235static int depmod_load_symvers(struct depmod *depmod, const char *filename)
2236{
2237 char line[10240];
2238 FILE *fp;
2239 unsigned int linenum = 0;
4a0e46da
GSB
2240
2241 fp = fopen(filename, "r");
035cbdc7
KR
2242 if (fp == NULL) {
2243 int err = -errno;
2244 DBG("load symvers: %s: %m\n", filename);
4a0e46da 2245 return err;
035cbdc7
KR
2246 }
2247 DBG("load symvers: %s\n", filename);
4a0e46da
GSB
2248
2249 /* eg. "0xb352177e\tfind_first_bit\tvmlinux\tEXPORT_SYMBOL" */
2250 while (fgets(line, sizeof(line), fp) != NULL) {
2251 const char *ver, *sym, *where;
2252 char *verend;
2253 uint64_t crc;
2254
2255 linenum++;
2256
2257 ver = strtok(line, " \t");
2258 sym = strtok(NULL, " \t");
2259 where = strtok(NULL, " \t");
2260 if (!ver || !sym || !where)
2261 continue;
2262
2263 if (!streq(where, "vmlinux"))
2264 continue;
2265
2266 crc = strtoull(ver, &verend, 16);
2267 if (verend[0] != '\0') {
2268 ERR("%s:%u Invalid symbol version %s: %m\n",
2269 filename, linenum, ver);
2270 continue;
2271 }
2272
572a2711 2273 depmod_symbol_add(depmod, sym, false, crc, NULL);
4a0e46da
GSB
2274 }
2275 depmod_add_fake_syms(depmod);
2276
035cbdc7 2277 DBG("loaded symvers: %s\n", filename);
4a0e46da
GSB
2278
2279 fclose(fp);
035cbdc7 2280 return 0;
4a0e46da
GSB
2281}
2282
2283static int depmod_load_system_map(struct depmod *depmod, const char *filename)
2284{
2285 const char ksymstr[] = "__ksymtab_";
2286 const size_t ksymstr_len = sizeof(ksymstr) - 1;
2287 char line[10240];
2288 FILE *fp;
2289 unsigned int linenum = 0;
4a0e46da
GSB
2290
2291 fp = fopen(filename, "r");
035cbdc7
KR
2292 if (fp == NULL) {
2293 int err = -errno;
2294 DBG("load System.map: %s: %m\n", filename);
4a0e46da 2295 return err;
035cbdc7
KR
2296 }
2297 DBG("load System.map: %s\n", filename);
4a0e46da
GSB
2298
2299 /* eg. c0294200 R __ksymtab_devfs_alloc_devnum */
2300 while (fgets(line, sizeof(line), fp) != NULL) {
2301 char *p, *end;
2302
2303 linenum++;
2304
2305 p = strchr(line, ' ');
2306 if (p == NULL)
2307 goto invalid_syntax;
2308 p++;
2309 p = strchr(p, ' ');
2310 if (p == NULL)
2311 goto invalid_syntax;
2312 p++;
2313
572a2711
AM
2314 /* skip prefix */
2315 if (p[0] == depmod->cfg->sym_prefix)
2316 p++;
2317
4a0e46da
GSB
2318 /* Covers gpl-only and normal symbols. */
2319 if (strncmp(p, ksymstr, ksymstr_len) != 0)
2320 continue;
2321
2322 end = strchr(p, '\n');
2323 if (end != NULL)
2324 *end = '\0';
2325
572a2711 2326 depmod_symbol_add(depmod, p + ksymstr_len, true, 0, NULL);
4a0e46da
GSB
2327 continue;
2328
2329 invalid_syntax:
2330 ERR("%s:%u: invalid line: %s\n", filename, linenum, line);
2331 }
2332 depmod_add_fake_syms(depmod);
2333
035cbdc7 2334 DBG("loaded System.map: %s\n", filename);
4a0e46da
GSB
2335
2336 fclose(fp);
035cbdc7 2337 return 0;
4a0e46da 2338}
25c41512 2339
18cd9da3
GSB
2340
2341static int depfile_up_to_date_dir(DIR *d, time_t mtime, size_t baselen, char *path)
2342{
2343 struct dirent *de;
2344 int err = 1, dfd = dirfd(d);
2345
2346 while ((de = readdir(d)) != NULL) {
2347 const char *name = de->d_name;
2348 size_t namelen;
2349 struct stat st;
2350
2351 if (name[0] == '.' && (name[1] == '\0' ||
2352 (name[1] == '.' && name[2] == '\0')))
2353 continue;
2354 if (streq(name, "build") || streq(name, "source"))
2355 continue;
2356 namelen = strlen(name);
2357 if (baselen + namelen + 2 >= PATH_MAX) {
2358 path[baselen] = '\0';
1958af88 2359 ERR("path is too long %s%s\n", path, name);
18cd9da3
GSB
2360 continue;
2361 }
2362
2363 if (fstatat(dfd, name, &st, 0) < 0) {
2364 ERR("fstatat(%d, %s): %m\n", dfd, name);
2365 continue;
2366 }
2367
2368 if (S_ISDIR(st.st_mode)) {
2369 int fd;
2370 DIR *subdir;
2371 memcpy(path + baselen, name, namelen + 1);
2372 if (baselen + namelen + 2 + NAME_MAX >= PATH_MAX) {
2373 ERR("directory path is too long %s\n", path);
2374 continue;
2375 }
2376 fd = openat(dfd, name, O_RDONLY);
2377 if (fd < 0) {
2378 ERR("openat(%d, %s, O_RDONLY): %m\n",
2379 dfd, name);
2380 continue;
2381 }
2382 subdir = fdopendir(fd);
2383 if (subdir == NULL) {
2384 ERR("fdopendir(%d): %m\n", fd);
2385 close(fd);
2386 continue;
2387 }
2388 path[baselen + namelen] = '/';
2389 path[baselen + namelen + 1] = '\0';
2390 err = depfile_up_to_date_dir(subdir, mtime,
2391 baselen + namelen + 1,
2392 path);
2393 closedir(subdir);
2394 } else if (S_ISREG(st.st_mode)) {
650f89cd 2395 if (!path_ends_with_kmod_ext(name, namelen))
18cd9da3 2396 continue;
650f89cd 2397
18cd9da3
GSB
2398 memcpy(path + baselen, name, namelen + 1);
2399 err = st.st_mtime <= mtime;
2400 if (err == 0) {
2401 DBG("%s %"PRIu64" is newer than %"PRIu64"\n",
2402 path, (uint64_t)st.st_mtime,
2403 (uint64_t)mtime);
2404 }
2405 } else {
2406 ERR("unsupported file type %s: %o\n",
2407 path, st.st_mode & S_IFMT);
2408 continue;
2409 }
2410
2411 if (err == 0)
2412 break; /* outdated! */
2413 else if (err < 0) {
2414 path[baselen + namelen] = '\0';
2415 ERR("failed %s: %s\n", path, strerror(-err));
2416 err = 1; /* ignore errors */
2417 }
2418 }
2419
2420 return err;
2421}
2422
2423/* uptodate: 1, outdated: 0, errors < 0 */
64b8b586
GSB
2424static int depfile_up_to_date(const char *dirname)
2425{
18cd9da3
GSB
2426 char path[PATH_MAX];
2427 DIR *d = opendir(dirname);
2428 struct stat st;
2429 size_t baselen;
2430 int err;
2431 if (d == NULL) {
2432 err = -errno;
63698377 2433 ERR("could not open directory %s: %m\n", dirname);
18cd9da3
GSB
2434 return err;
2435 }
2436
2437 if (fstatat(dirfd(d), "modules.dep", &st, 0) != 0) {
2438 err = -errno;
63698377 2439 ERR("could not fstatat(%s, modules.dep): %m\n", dirname);
18cd9da3
GSB
2440 closedir(d);
2441 return err;
2442 }
2443
2444 baselen = strlen(dirname);
2445 memcpy(path, dirname, baselen);
2446 path[baselen] = '/';
2447 baselen++;
2448 path[baselen] = '\0';
2449
2450 err = depfile_up_to_date_dir(d, st.st_mtime, baselen, path);
2451 closedir(d);
2452 return err;
64b8b586
GSB
2453}
2454
2455static int is_version_number(const char *version)
2456{
2457 unsigned int d1, d2;
2458 return (sscanf(version, "%u.%u", &d1, &d2) == 2);
2459}
2460
f6cf14ce 2461static int do_depmod(int argc, char *argv[])
64b8b586
GSB
2462{
2463 FILE *out = NULL;
31f1d0d3 2464 int err = 0, all = 0, maybe_all = 0, n_config_paths = 0;
e15a56af 2465 char *root = NULL;
64b8b586 2466 const char **config_paths = NULL;
64b8b586
GSB
2467 const char *system_map = NULL;
2468 const char *module_symvers = NULL;
2469 const char *null_kmod_config = NULL;
2470 struct utsname un;
2471 struct kmod_ctx *ctx = NULL;
2472 struct cfg cfg;
2473 struct depmod depmod;
2474
2475 memset(&cfg, 0, sizeof(cfg));
2476 memset(&depmod, 0, sizeof(depmod));
2477
2478 for (;;) {
2479 int c, idx = 0;
2480 c = getopt_long(argc, argv, cmdopts_s, cmdopts, &idx);
2481 if (c == -1)
2482 break;
2483 switch (c) {
2484 case 'a':
2485 all = 1;
2486 break;
2487 case 'A':
2488 maybe_all = 1;
2489 break;
2490 case 'b':
e15a56af 2491 root = path_make_absolute_cwd(optarg);
64b8b586
GSB
2492 break;
2493 case 'C': {
2494 size_t bytes = sizeof(char *) * (n_config_paths + 2);
2495 void *tmp = realloc(config_paths, bytes);
2496 if (!tmp) {
2497 fputs("Error: out-of-memory\n", stderr);
2498 goto cmdline_failed;
2499 }
2500 config_paths = tmp;
2501 config_paths[n_config_paths] = optarg;
2502 n_config_paths++;
2503 config_paths[n_config_paths] = NULL;
2504 break;
2505 }
2506 case 'E':
2507 module_symvers = optarg;
2508 cfg.check_symvers = 1;
2509 break;
2510 case 'F':
2511 system_map = optarg;
2512 break;
2513 case 'e':
2514 cfg.print_unknown = 1;
2515 break;
2516 case 'v':
2517 verbose++;
2518 break;
2519 case 'n':
2520 out = stdout;
2521 break;
2522 case 'P':
2523 if (optarg[1] != '\0') {
2524 CRIT("-P only takes a single char\n");
2525 goto cmdline_failed;
2526 }
2527 cfg.sym_prefix = optarg[0];
2528 break;
2529 case 'w':
2530 cfg.warn_dups = 1;
2531 break;
2532 case 'u':
2533 case 'q':
2534 case 'r':
2535 case 'm':
61c48db3
LDM
2536 if (idx > 0)
2537 WRN("Ignored deprecated option --%s\n",
2538 cmdopts[idx].name);
2539 else
2540 WRN("Ignored deprecated option -%c\n", c);
2541
64b8b586
GSB
2542 break;
2543 case 'h':
4a2e20df 2544 help();
64b8b586
GSB
2545 free(config_paths);
2546 return EXIT_SUCCESS;
2547 case 'V':
2548 puts(PACKAGE " version " VERSION);
2549 free(config_paths);
2550 return EXIT_SUCCESS;
2551 case '?':
2552 goto cmdline_failed;
2553 default:
61c48db3 2554 ERR("unexpected getopt_long() value '%c'.\n", c);
64b8b586
GSB
2555 goto cmdline_failed;
2556 }
2557 }
2558
2559 if (optind < argc && is_version_number(argv[optind])) {
2560 cfg.kversion = argv[optind];
2561 optind++;
2562 } else {
2563 if (uname(&un) < 0) {
2564 CRIT("uname() failed: %s\n", strerror(errno));
2565 goto cmdline_failed;
2566 }
2567 cfg.kversion = un.release;
2568 }
2569
2570 cfg.dirnamelen = snprintf(cfg.dirname, PATH_MAX,
c5b37dba 2571 "%s/lib/modules/%s",
e15a56af 2572 root == NULL ? "" : root, cfg.kversion);
64b8b586
GSB
2573
2574 if (optind == argc)
2575 all = 1;
2576
2577 if (maybe_all) {
2578 if (out == stdout)
2579 goto done;
18cd9da3
GSB
2580 /* ignore up-to-date errors (< 0) */
2581 if (depfile_up_to_date(cfg.dirname) == 1) {
2582 DBG("%s/modules.dep is up to date!\n", cfg.dirname);
64b8b586 2583 goto done;
18cd9da3
GSB
2584 }
2585 DBG("%s/modules.dep is outdated, do -a\n", cfg.dirname);
64b8b586
GSB
2586 all = 1;
2587 }
2588
2589 ctx = kmod_new(cfg.dirname, &null_kmod_config);
2590 if (ctx == NULL) {
2591 CRIT("kmod_new(\"%s\", {NULL}) failed: %m\n", cfg.dirname);
2592 goto cmdline_failed;
2593 }
52a50fe2
LDM
2594
2595 log_setup_kmod_log(ctx, verbose);
64b8b586
GSB
2596
2597 err = depmod_init(&depmod, &cfg, ctx);
2598 if (err < 0) {
2599 CRIT("depmod_init: %s\n", strerror(-err));
2600 goto depmod_init_failed;
2601 }
2602 ctx = NULL; /* owned by depmod */
2603
4a0e46da
GSB
2604 if (module_symvers != NULL) {
2605 err = depmod_load_symvers(&depmod, module_symvers);
2606 if (err < 0) {
63698377 2607 CRIT("could not load %s: %s\n", module_symvers,
4a0e46da
GSB
2608 strerror(-err));
2609 goto cmdline_failed;
2610 }
2611 } else if (system_map != NULL) {
2612 err = depmod_load_system_map(&depmod, system_map);
2613 if (err < 0) {
035cbdc7 2614 CRIT("could not load %s: %s\n", system_map,
4a0e46da
GSB
2615 strerror(-err));
2616 goto cmdline_failed;
2617 }
2618 } else if (cfg.print_unknown) {
2619 WRN("-e needs -E or -F\n");
2620 cfg.print_unknown = 0;
2621 }
2622
64b8b586
GSB
2623 if (all) {
2624 err = cfg_load(&cfg, config_paths);
2625 if (err < 0) {
63698377 2626 CRIT("could not load configuration files\n");
64b8b586
GSB
2627 goto cmdline_modules_failed;
2628 }
2629 err = depmod_modules_search(&depmod);
2630 if (err < 0) {
63698377 2631 CRIT("could not search modules: %s\n", strerror(-err));
64b8b586
GSB
2632 goto cmdline_modules_failed;
2633 }
2634 } else {
31f1d0d3
LDM
2635 int i;
2636
64b8b586
GSB
2637 for (i = optind; i < argc; i++) {
2638 const char *path = argv[i];
2639 struct kmod_module *mod;
2640
2641 if (path[0] != '/') {
b0bcadd0 2642 CRIT("%s: not absolute path.\n", path);
64b8b586
GSB
2643 goto cmdline_modules_failed;
2644 }
2645
2646 err = kmod_module_new_from_path(depmod.ctx, path, &mod);
2647 if (err < 0) {
63698377 2648 CRIT("could not create module %s: %s\n",
64b8b586
GSB
2649 path, strerror(-err));
2650 goto cmdline_modules_failed;
2651 }
2652
2653 err = depmod_module_add(&depmod, mod);
2654 if (err < 0) {
63698377 2655 CRIT("could not add module %s: %s\n",
64b8b586
GSB
2656 path, strerror(-err));
2657 kmod_module_unref(mod);
2658 goto cmdline_modules_failed;
2659 }
2660 }
2661 }
2662
00bd3191
JAS
2663 err = depmod_modules_build_array(&depmod);
2664 if (err < 0) {
2665 CRIT("could not build module array: %s\n",
2666 strerror(-err));
2667 goto cmdline_modules_failed;
2668 }
2669
64b8b586
GSB
2670 depmod_modules_sort(&depmod);
2671 err = depmod_load(&depmod);
2672 if (err < 0)
2673 goto cmdline_modules_failed;
2674
25c41512 2675 err = depmod_output(&depmod, out);
64b8b586
GSB
2676
2677done:
2678 depmod_shutdown(&depmod);
2679 cfg_free(&cfg);
2680 free(config_paths);
2681 return err >= 0 ? EXIT_SUCCESS : EXIT_FAILURE;
2682
2683cmdline_modules_failed:
2684 depmod_shutdown(&depmod);
2685depmod_init_failed:
2686 if (ctx != NULL)
2687 kmod_unref(ctx);
2688cmdline_failed:
2689 cfg_free(&cfg);
2690 free(config_paths);
e15a56af 2691 free(root);
64b8b586
GSB
2692 return EXIT_FAILURE;
2693}
f6cf14ce 2694
f6cf14ce
LDM
2695const struct kmod_cmd kmod_cmd_compat_depmod = {
2696 .name = "depmod",
2697 .cmd = do_depmod,
2698 .help = "compat depmod command",
2699};