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