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