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