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