]> git.ipfire.org Git - thirdparty/kmod.git/blame - tools/depmod.c
depmod: fail if any index could not be created
[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
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);
035cbdc7 944 DBG("parsed configuration files from %s\n", path);
64b8b586
GSB
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;
18a492e6 1245 int err;
64b8b586 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);
20c6e18c 1405 return err;
64b8b586
GSB
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) {
819f79a2
DR
1545 if (err == -ENOENT)
1546 DBG("ignoring %s: no symbols\n", mod->path);
1547 else
1548 ERR("failed to load symbols from %s: %s\n",
1549 mod->path, strerror(-err));
64b8b586
GSB
1550 continue;
1551 }
1552 kmod_list_foreach(l, list) {
1553 const char *name = kmod_module_symbol_get_symbol(l);
1554 uint64_t crc = kmod_module_symbol_get_crc(l);
1555 depmod_symbol_add(depmod, name, crc, mod);
1556 }
1557 kmod_module_symbols_free_list(list);
1558 }
1559
1560 DBG("loaded symbols (%zd modules, %zd symbols)\n",
1561 depmod->modules.count, hash_get_count(depmod->symbols));
1562
1563 return 0;
1564}
1565
1566static int depmod_load_module_dependencies(struct depmod *depmod, struct mod *mod)
1567{
1568 const struct cfg *cfg = depmod->cfg;
1569 struct kmod_list *l, *list = NULL;
1570 int err = kmod_module_get_dependency_symbols(mod->kmod, &list);
1571 if (err < 0) {
1572 DBG("ignoring %s: no dependency symbols: %s\n",
1573 mod->path, strerror(-err));
1574 return 0;
1575 }
1576
1577 DBG("do dependencies of %s\n", mod->path);
1578 kmod_list_foreach(l, list) {
1579 const char *name = kmod_module_dependency_symbol_get_symbol(l);
1580 uint64_t crc = kmod_module_dependency_symbol_get_crc(l);
0de40463 1581 int bindtype = kmod_module_dependency_symbol_get_bind(l);
64b8b586 1582 struct symbol *sym = depmod_symbol_find(depmod, name);
0de40463 1583 uint8_t is_weak = bindtype == KMOD_SYMBOL_WEAK;
64b8b586
GSB
1584
1585 if (sym == NULL) {
1586 DBG("%s needs (%c) unknown symbol %s\n",
0de40463 1587 mod->path, bindtype, name);
64b8b586
GSB
1588 if (cfg->print_unknown && !is_weak)
1589 WRN("%s needs unknown symbol %s\n",
1590 mod->path, name);
1591 continue;
1592 }
1593
1594 if (cfg->check_symvers && sym->crc != crc && !is_weak) {
1595 DBG("symbol %s (%#"PRIx64") module %s (%#"PRIx64")\n",
1596 sym->name, sym->crc, mod->path, crc);
1597 if (cfg->print_unknown)
1598 WRN("%s disagrees about version of symbol %s\n",
1599 mod->path, name);
1600 }
1601
1602 mod_add_dependency(mod, sym);
1603 }
1604 kmod_module_dependency_symbols_free_list(list);
1605 return 0;
1606}
1607
1608static int depmod_load_dependencies(struct depmod *depmod)
1609{
1610 struct mod **itr, **itr_end;
1611
1612 DBG("load dependencies (%zd modules, %zd symbols)\n",
1613 depmod->modules.count, hash_get_count(depmod->symbols));
1614
1615 itr = (struct mod **)depmod->modules.array;
1616 itr_end = itr + depmod->modules.count;
1617 for (; itr < itr_end; itr++) {
1618 struct mod *mod = *itr;
1619 depmod_load_module_dependencies(depmod, mod);
1620 }
1621
1622 DBG("loaded dependencies (%zd modules, %zd symbols)\n",
1623 depmod->modules.count, hash_get_count(depmod->symbols));
1624
1625 return 0;
1626}
1627
1628static int dep_cmp(const void *pa, const void *pb)
1629{
1630 const struct mod *a = *(const struct mod **)pa;
1631 const struct mod *b = *(const struct mod **)pb;
1632 if (a->dep_loop == b->dep_loop)
1633 return a->dep_sort_idx - b->dep_sort_idx;
1634 else if (a->dep_loop)
1635 return 1;
1636 else if (b->dep_loop)
1637 return -1;
1638 return a->dep_sort_idx - b->dep_sort_idx;
1639}
1640
1641static void depmod_sort_dependencies(struct depmod *depmod)
1642{
1643 struct mod **itr, **itr_end;
1644 itr = (struct mod **)depmod->modules.array;
1645 itr_end = itr + depmod->modules.count;
1646 for (; itr < itr_end; itr++) {
1647 struct mod *m = *itr;
1648 if (m->deps.count > 1)
1649 array_sort(&m->deps, dep_cmp);
1650 }
1651}
1652
1653static int depmod_calculate_dependencies(struct depmod *depmod)
1654{
1655 const struct mod **itrm;
1656 uint16_t *users, *roots, *sorted;
1657 uint16_t i, n_roots = 0, n_sorted = 0, n_mods = depmod->modules.count;
1658
1659 users = malloc(sizeof(uint16_t) * n_mods * 3);
1660 if (users == NULL)
1661 return -ENOMEM;
1662 roots = users + n_mods;
1663 sorted = roots + n_mods;
1664
1665 DBG("calculate dependencies and ordering (%zd modules)\n", n_mods);
1666
1667 assert(depmod->modules.count < UINT16_MAX);
1668
1669 /* populate modules users (how many modules uses it) */
1670 itrm = (const struct mod **)depmod->modules.array;
1671 for (i = 0; i < n_mods; i++, itrm++) {
1672 const struct mod *m = *itrm;
1673 users[i] = m->users;
1674 if (users[i] == 0) {
1675 roots[n_roots] = i;
1676 n_roots++;
1677 }
1678 }
1679
1680 /* topological sort (outputs modules without users first) */
1681 while (n_roots > 0) {
1682 const struct mod **itr_dst, **itr_dst_end;
1683 struct mod *src;
1684 uint16_t src_idx = roots[--n_roots];
1685
1686 src = depmod->modules.array[src_idx];
1687 src->dep_sort_idx = n_sorted;
1688 sorted[n_sorted] = src_idx;
1689 n_sorted++;
1690
1691 itr_dst = (const struct mod **)src->deps.array;
1692 itr_dst_end = itr_dst + src->deps.count;
1693 for (; itr_dst < itr_dst_end; itr_dst++) {
1694 const struct mod *dst = *itr_dst;
1695 uint16_t dst_idx = dst->idx;
1696 assert(users[dst_idx] > 0);
1697 users[dst_idx]--;
1698 if (users[dst_idx] == 0) {
1699 roots[n_roots] = dst_idx;
1700 n_roots++;
1701 }
1702 }
1703 }
1704
1705 if (n_sorted < n_mods) {
1706 WRN("found %hu modules in dependency cycles!\n",
1707 n_mods - n_sorted);
1708 for (i = 0; i < n_mods; i++) {
1709 struct mod *m;
1710 if (users[i] == 0)
1711 continue;
1712 m = depmod->modules.array[i];
1713 WRN("%s in dependency cycle!\n", m->path);
1714 m->dep_loop = 1;
1715 m->dep_sort_idx = INT32_MAX;
1716 depmod->dep_loops++;
1717 }
1718 }
1719
1720 depmod_sort_dependencies(depmod);
1721
1722 DBG("calculated dependencies and ordering (%u loops, %zd modules)\n",
1723 depmod->dep_loops, n_mods);
1724
1725 free(users);
1726 return 0;
1727}
1728
1729static int depmod_load(struct depmod *depmod)
1730{
1731 int err;
1732
1733 err = depmod_load_symbols(depmod);
1734 if (err < 0)
1735 return err;
1736
1737 err = depmod_load_dependencies(depmod);
1738 if (err < 0)
1739 return err;
1740
1741 err = depmod_calculate_dependencies(depmod);
1742 if (err < 0)
1743 return err;
1744
1745 return 0;
1746}
1747
8e3505c5
GSB
1748static size_t mod_count_all_dependencies(const struct mod *mod)
1749{
1750 size_t i, count = 0;
1751 for (i = 0; i < mod->deps.count; i++) {
1752 const struct mod *d = mod->deps.array[i];
1753 count += 1 + mod_count_all_dependencies(d);
1754 }
1755 return count;
1756}
1757
1758static int mod_fill_all_unique_dependencies(const struct mod *mod, const struct mod **deps, size_t n_deps, size_t *last)
1759{
1760 size_t i;
1761 int err = 0;
1762 for (i = 0; i < mod->deps.count; i++) {
1763 const struct mod *d = mod->deps.array[i];
1764 size_t j;
1765 uint8_t exists = 0;
1766
1767 for (j = 0; j < *last; j++) {
1768 if (deps[j] == d) {
1769 exists = 1;
1770 break;
1771 }
1772 }
1773
1774 if (exists)
1775 continue;
1776
1777 if (*last >= n_deps)
1778 return -ENOSPC;
1779 deps[*last] = d;
1780 (*last)++;
1781 err = mod_fill_all_unique_dependencies(d, deps, n_deps, last);
1782 if (err < 0)
1783 break;
1784 }
1785 return err;
1786}
1787
1788static const struct mod **mod_get_all_sorted_dependencies(const struct mod *mod, size_t *n_deps)
1789{
1790 const struct mod **deps;
1791 size_t last = 0;
1792
1793 *n_deps = mod_count_all_dependencies(mod);
1794 if (*n_deps == 0)
1795 return NULL;
1796
1797 deps = malloc(sizeof(struct mod *) * (*n_deps));
1798 if (deps == NULL)
1799 return NULL;
1800
1801 if (mod_fill_all_unique_dependencies(mod, deps, *n_deps, &last) < 0) {
1802 free(deps);
1803 return NULL;
1804 }
1805
1806 qsort(deps, last, sizeof(struct mod *), dep_cmp);
1807 *n_deps = last;
1808 return deps;
1809}
1810
1811static inline const char *mod_get_compressed_path(const struct mod *mod)
1812{
1813 if (mod->relpath != NULL)
1814 return mod->relpath;
1815 return mod->path;
1816}
1817
1818static int output_deps(struct depmod *depmod, FILE *out)
1819{
1820 size_t i;
1821
1822 for (i = 0; i < depmod->modules.count; i++) {
1823 const struct mod **deps, *mod = depmod->modules.array[i];
1824 const char *p = mod_get_compressed_path(mod);
1825 size_t j, n_deps;
1826
1827 if (mod->dep_loop) {
1828 DBG("Ignored %s due dependency loops\n", p);
1829 continue;
1830 }
1831
1832 fprintf(out, "%s:", p);
1833
1834 if (mod->deps.count == 0)
1835 goto end;
1836
1837 deps = mod_get_all_sorted_dependencies(mod, &n_deps);
1838 if (deps == NULL) {
63698377 1839 ERR("could not get all sorted dependencies of %s\n", p);
8e3505c5
GSB
1840 goto end;
1841 }
1842
1843 for (j = 0; j < n_deps; j++) {
1844 const struct mod *d = deps[j];
1845 if (d->dep_loop) {
1846 DBG("Ignored %s (dependency of %s) "
1847 "due dependency loops\n",
1848 mod_get_compressed_path(d), p);
1849 continue;
1850 }
1851 fprintf(out, " %s", mod_get_compressed_path(d));
1852 }
1853 free(deps);
1854 end:
1855 putc('\n', out);
1856 }
1857
1858 return 0;
1859}
1860
7436788c
GSB
1861static int output_deps_bin(struct depmod *depmod, FILE *out)
1862{
1863 struct index_node *idx;
1864 size_t i;
1865
1866 if (out == stdout)
1867 return 0;
1868
1869 idx = index_create();
1870 if (idx == NULL)
1871 return -ENOMEM;
1872
1873 for (i = 0; i < depmod->modules.count; i++) {
1874 const struct mod **deps, *mod = depmod->modules.array[i];
1875 const char *p = mod_get_compressed_path(mod);
1876 char *line;
1877 size_t j, n_deps, linepos, linelen, slen;
1878 int duplicate;
1879
1880 if (mod->dep_loop) {
1881 DBG("Ignored %s due dependency loops\n", p);
1882 continue;
1883 }
1884
1885 deps = mod_get_all_sorted_dependencies(mod, &n_deps);
1886 if (deps == NULL && n_deps > 0) {
63698377 1887 ERR("could not get all sorted dependencies of %s\n", p);
7436788c
GSB
1888 continue;
1889 }
1890
1891 linelen = strlen(p) + 1;
1892 for (j = 0; j < n_deps; j++) {
1893 const struct mod *d = deps[j];
1894 if (d->dep_loop) {
1895 DBG("Ignored %s (dependency of %s) "
1896 "due dependency loops\n",
1897 mod_get_compressed_path(d), p);
1898 continue;
1899 }
1900 linelen += 1 + strlen(mod_get_compressed_path(d));
1901 }
1902
1903 line = malloc(linelen + 1);
1904 if (line == NULL) {
1905 free(deps);
1906 ERR("modules.deps.bin: out of memory\n");
1907 continue;
1908 }
1909
1910 linepos = 0;
1911 slen = strlen(p);
1912 memcpy(line + linepos, p, slen);
1913 linepos += slen;
1914 line[linepos] = ':';
1915 linepos++;
1916
1917 for (j = 0; j < n_deps; j++) {
1918 const struct mod *d = deps[j];
1919 const char *dp;
1920 if (d->dep_loop)
1921 continue;
1922 line[linepos] = ' ';
1923 linepos++;
1924
1925 dp = mod_get_compressed_path(d);
1926 slen = strlen(dp);
1927 memcpy(line + linepos, dp, slen);
1928 linepos += slen;
1929 }
1930 line[linepos] = '\0';
1931
1932 duplicate = index_insert(idx, mod->modname, line, mod->idx);
1933 if (duplicate && depmod->cfg->warn_dups)
1934 WRN("duplicate module deps:\n%s\n", line);
1935 free(line);
ea1b8c37 1936 free(deps);
7436788c
GSB
1937 }
1938
1939 index_write(idx, out);
1940 index_destroy(idx);
1941
1942 return 0;
1943}
1944
0d131745
GSB
1945static int output_aliases(struct depmod *depmod, FILE *out)
1946{
1947 size_t i;
1948
1949 fputs("# Aliases extracted from modules themselves.\n", out);
1950
1951 for (i = 0; i < depmod->modules.count; i++) {
1952 const struct mod *mod = depmod->modules.array[i];
1953 struct kmod_list *l, *list = NULL;
1954 int r = kmod_module_get_info(mod->kmod, &list);
1955 if (r < 0 || list == NULL)
1956 continue;
1957 kmod_list_foreach(l, list) {
1958 const char *key = kmod_module_info_get_key(l);
1959 const char *value = kmod_module_info_get_value(l);
1960
1961 if (!streq(key, "alias"))
1962 continue;
1963
1964 fprintf(out, "alias %s %s\n",
1965 value, kmod_module_get_name(mod->kmod));
1966 }
1967 kmod_module_info_free_list(list);
1968 }
1969
1970 return 0;
1971}
1972
ec77abb9
GSB
1973static int output_aliases_bin(struct depmod *depmod, FILE *out)
1974{
1975 char buf[1024];
1976 struct index_node *idx;
1977 size_t i;
1978
1979 if (out == stdout)
1980 return 0;
1981
1982 idx = index_create();
1983 if (idx == NULL)
1984 return -ENOMEM;
1985
1986 for (i = 0; i < depmod->modules.count; i++) {
1987 const struct mod *mod = depmod->modules.array[i];
1988 struct kmod_list *l, *list = NULL;
1989 int r = kmod_module_get_info(mod->kmod, &list);
1990 if (r < 0 || list == NULL)
1991 continue;
1992 kmod_list_foreach(l, list) {
1993 const char *key = kmod_module_info_get_key(l);
1994 const char *value = kmod_module_info_get_value(l);
1995 const char *modname, *alias;
1996 int duplicate;
1997
1998 if (!streq(key, "alias"))
1999 continue;
2000
0c010fae 2001 alias = underscores2(value, buf, sizeof(buf));
ec77abb9
GSB
2002 if (alias == NULL)
2003 continue;
2004
2005 modname = kmod_module_get_name(mod->kmod);
2006 duplicate = index_insert(idx, alias, modname,
2007 mod->idx);
2008 if (duplicate && depmod->cfg->warn_dups)
2009 WRN("duplicate module alias:\n%s %s\n",
2010 alias, modname);
2011 }
2012 kmod_module_info_free_list(list);
2013 }
2014
2015 index_write(idx, out);
2016 index_destroy(idx);
2017
2018 return 0;
2019}
2020
8bc830ef
GSB
2021static int output_softdeps(struct depmod *depmod, FILE *out)
2022{
2023 size_t i;
2024
2025 fputs("# Soft dependencies extracted from modules themselves.\n", out);
2026 fputs("# Copy, with a .conf extension, to /etc/modprobe.d to use "
2027 "it with modprobe.\n", out);
2028
2029 for (i = 0; i < depmod->modules.count; i++) {
2030 const struct mod *mod = depmod->modules.array[i];
2031 struct kmod_list *l, *list = NULL;
2032 int r = kmod_module_get_info(mod->kmod, &list);
2033 if (r < 0 || list == NULL)
2034 continue;
2035 kmod_list_foreach(l, list) {
2036 const char *key = kmod_module_info_get_key(l);
2037 const char *value = kmod_module_info_get_value(l);
2038
2039 if (!streq(key, "softdep"))
2040 continue;
2041
2042 fprintf(out, "softdep %s %s\n",
2043 kmod_module_get_name(mod->kmod), value);
2044 }
2045 kmod_module_info_free_list(list);
2046 }
2047
2048 return 0;
2049}
2050
9a14d0e9
GSB
2051static int output_symbols(struct depmod *depmod, FILE *out)
2052{
5cd13064 2053 struct hash_iter iter;
55021bed 2054 const void *v;
9a14d0e9
GSB
2055
2056 fputs("# Aliases for symbols, used by symbol_request().\n", out);
2057
5cd13064
LDM
2058 hash_iter_init(depmod->symbols, &iter);
2059
55021bed
REB
2060 while (hash_iter_next(&iter, NULL, &v)) {
2061 const struct symbol *sym = v;
5cd13064
LDM
2062 if (sym->owner == NULL)
2063 continue;
2064
2065 fprintf(out, "alias symbol:%s %s\n",
2066 sym->name, sym->owner->modname);
9a14d0e9
GSB
2067 }
2068
2069 return 0;
2070}
2071
75a9723b
GSB
2072static int output_symbols_bin(struct depmod *depmod, FILE *out)
2073{
2074 struct index_node *idx;
2075 char alias[1024];
5cd13064
LDM
2076 size_t baselen = sizeof("symbol:") - 1;
2077 struct hash_iter iter;
55021bed 2078 const void *v;
75a9723b
GSB
2079
2080 if (out == stdout)
2081 return 0;
2082
2083 idx = index_create();
2084 if (idx == NULL)
2085 return -ENOMEM;
2086
2087 memcpy(alias, "symbol:", baselen);
5cd13064 2088 hash_iter_init(depmod->symbols, &iter);
75a9723b 2089
55021bed 2090 while (hash_iter_next(&iter, NULL, &v)) {
5cd13064 2091 int duplicate;
55021bed 2092 const struct symbol *sym = v;
75a9723b 2093
5cd13064
LDM
2094 if (sym->owner == NULL)
2095 continue;
75a9723b 2096
5cd13064
LDM
2097 strcpy(alias + baselen, sym->name);
2098 duplicate = index_insert(idx, alias, sym->owner->modname,
2099 sym->owner->idx);
2100
2101 if (duplicate && depmod->cfg->warn_dups)
2102 WRN("duplicate module syms:\n%s %s\n",
2103 alias, sym->owner->modname);
75a9723b
GSB
2104 }
2105
2106 index_write(idx, out);
2107 index_destroy(idx);
5cd13064 2108
75a9723b
GSB
2109 return 0;
2110}
2111
4b144e5f
GSB
2112static int output_builtin_bin(struct depmod *depmod, FILE *out)
2113{
2114 FILE *in;
2115 struct index_node *idx;
6daceb2f 2116 char infile[PATH_MAX], line[PATH_MAX], modname[PATH_MAX];
4b144e5f
GSB
2117
2118 if (out == stdout)
2119 return 0;
2120
2121 snprintf(infile, sizeof(infile), "%s/modules.builtin",
c5db1a3f 2122 depmod->cfg->dirname);
4b144e5f
GSB
2123 in = fopen(infile, "r");
2124 if (in == NULL) {
56406fdb 2125 WRN("could not open %s: %m\n", infile);
c5db1a3f 2126 return 0;
4b144e5f
GSB
2127 }
2128
2129 idx = index_create();
2130 if (idx == NULL) {
2131 fclose(in);
2132 return -ENOMEM;
2133 }
2134
2135 while (fgets(line, sizeof(line), in) != NULL) {
2136 if (!isalpha(line[0])) {
2137 ERR("Invalid modules.builtin line: %s\n", line);
2138 continue;
2139 }
2140
2141 path_to_modname(line, modname, NULL);
2142 index_insert(idx, modname, "", 0);
2143 }
2144
2145 index_write(idx, out);
2146 index_destroy(idx);
2147 fclose(in);
2148
2149 return 0;
2150}
2151
25c41512
GSB
2152static int output_devname(struct depmod *depmod, FILE *out)
2153{
2154 size_t i;
2155
2156 fputs("# Device nodes to trigger on-demand module loading.\n", out);
2157
2158 for (i = 0; i < depmod->modules.count; i++) {
2159 const struct mod *mod = depmod->modules.array[i];
2160 struct kmod_list *l, *list = NULL;
2161 const char *devname = NULL;
2162 char type = '\0';
2163 unsigned int major = 0, minor = 0;
2164 int r;
2165
2166 r = kmod_module_get_info(mod->kmod, &list);
2167 if (r < 0 || list == NULL)
2168 continue;
2169
2170 kmod_list_foreach(l, list) {
2171 const char *key = kmod_module_info_get_key(l);
2172 const char *value = kmod_module_info_get_value(l);
2173 unsigned int maj, min;
2174
2175 if (!streq(key, "alias"))
2176 continue;
2177
2178 if (strstartswith(value, "devname:"))
2179 devname = value + sizeof("devname:") - 1;
2180 else if (sscanf(value, "char-major-%u-%u",
2181 &maj, &min) == 2) {
2182 type = 'c';
2183 major = maj;
2184 minor = min;
2185 } else if (sscanf(value, "block-major-%u-%u",
2186 &maj, &min) == 2) {
2187 type = 'b';
2188 major = maj;
2189 minor = min;
2190 }
2191
2192 if (type != '\0' && devname != NULL) {
2193 fprintf(out, "%s %s %c%u:%u\n",
2194 kmod_module_get_name(mod->kmod),
2195 devname, type, major, minor);
2196 break;
2197 }
2198 }
2199 kmod_module_info_free_list(list);
2200 }
2201
2202 return 0;
2203}
2204
2205static int depmod_output(struct depmod *depmod, FILE *out)
2206{
2207 static const struct depfile {
2208 const char *name;
2209 int (*cb)(struct depmod *depmod, FILE *out);
2210 } *itr, depfiles[] = {
8e3505c5 2211 {"modules.dep", output_deps},
7436788c 2212 {"modules.dep.bin", output_deps_bin},
0d131745 2213 {"modules.alias", output_aliases},
ec77abb9 2214 {"modules.alias.bin", output_aliases_bin},
8bc830ef 2215 {"modules.softdep", output_softdeps},
9a14d0e9 2216 {"modules.symbols", output_symbols},
75a9723b 2217 {"modules.symbols.bin", output_symbols_bin},
4b144e5f 2218 {"modules.builtin.bin", output_builtin_bin},
25c41512
GSB
2219 {"modules.devname", output_devname},
2220 {NULL, NULL}
2221 };
2222 const char *dname = depmod->cfg->dirname;
2223 int dfd, err = 0;
2224
2225 if (out != NULL)
2226 dfd = -1;
2227 else {
2228 dfd = open(dname, O_RDONLY);
2229 if (dfd < 0) {
2230 err = -errno;
63698377 2231 CRIT("could not open directory %s: %m\n", dname);
25c41512
GSB
2232 return err;
2233 }
2234 }
2235
2236 for (itr = depfiles; itr->name != NULL; itr++) {
2237 FILE *fp = out;
2238 char tmp[NAME_MAX] = "";
2239 int r;
2240
2241 if (fp == NULL) {
2242 int flags = O_CREAT | O_TRUNC | O_WRONLY;
2243 int mode = 0644;
2244 int fd;
2245
2246 snprintf(tmp, sizeof(tmp), "%s.tmp", itr->name);
2247 fd = openat(dfd, tmp, flags, mode);
2248 if (fd < 0) {
2249 ERR("openat(%s, %s, %o, %o): %m\n",
2250 dname, tmp, flags, mode);
2251 continue;
2252 }
2253 fp = fdopen(fd, "wb");
2254 if (fp == NULL) {
2255 ERR("fdopen(%d=%s/%s): %m\n", fd, dname, tmp);
2256 close(fd);
2257 continue;
2258 }
2259 }
2260
2261 r = itr->cb(depmod, fp);
2262 if (fp == out)
2263 continue;
2264
2265 fclose(fp);
2266 if (r < 0) {
2267 if (unlinkat(dfd, tmp, 0) != 0)
2268 ERR("unlinkat(%s, %s): %m\n", dname, tmp);
80e49ad9
LDM
2269
2270 ERR("Could not write index '%s': %s\n", itr->name,
2271 strerror(-r));
2272 err = -errno;
2273 break;
2274 }
2275
2276 unlinkat(dfd, itr->name, 0);
2277 if (renameat(dfd, tmp, dfd, itr->name) != 0) {
2278 err = -errno;
2279 CRIT("renameat(%s, %s, %s, %s): %m\n",
2280 dname, tmp, dname, itr->name);
2281 break;
25c41512
GSB
2282 }
2283 }
2284
2285 if (dfd >= 0)
2286 close(dfd);
80e49ad9 2287
25c41512
GSB
2288 return err;
2289}
2290
4a0e46da
GSB
2291static void depmod_add_fake_syms(struct depmod *depmod)
2292{
2293 /* __this_module is magic inserted by kernel loader. */
2294 depmod_symbol_add(depmod, "__this_module", 0, NULL);
2295 /* On S390, this is faked up too */
2296 depmod_symbol_add(depmod, "_GLOBAL_OFFSET_TABLE_", 0, NULL);
2297}
2298
2299static int depmod_load_symvers(struct depmod *depmod, const char *filename)
2300{
2301 char line[10240];
2302 FILE *fp;
2303 unsigned int linenum = 0;
4a0e46da
GSB
2304
2305 fp = fopen(filename, "r");
035cbdc7
KR
2306 if (fp == NULL) {
2307 int err = -errno;
2308 DBG("load symvers: %s: %m\n", filename);
4a0e46da 2309 return err;
035cbdc7
KR
2310 }
2311 DBG("load symvers: %s\n", filename);
4a0e46da
GSB
2312
2313 /* eg. "0xb352177e\tfind_first_bit\tvmlinux\tEXPORT_SYMBOL" */
2314 while (fgets(line, sizeof(line), fp) != NULL) {
2315 const char *ver, *sym, *where;
2316 char *verend;
2317 uint64_t crc;
2318
2319 linenum++;
2320
2321 ver = strtok(line, " \t");
2322 sym = strtok(NULL, " \t");
2323 where = strtok(NULL, " \t");
2324 if (!ver || !sym || !where)
2325 continue;
2326
2327 if (!streq(where, "vmlinux"))
2328 continue;
2329
2330 crc = strtoull(ver, &verend, 16);
2331 if (verend[0] != '\0') {
2332 ERR("%s:%u Invalid symbol version %s: %m\n",
2333 filename, linenum, ver);
2334 continue;
2335 }
2336
2337 depmod_symbol_add(depmod, sym, crc, NULL);
2338 }
2339 depmod_add_fake_syms(depmod);
2340
035cbdc7 2341 DBG("loaded symvers: %s\n", filename);
4a0e46da
GSB
2342
2343 fclose(fp);
035cbdc7 2344 return 0;
4a0e46da
GSB
2345}
2346
2347static int depmod_load_system_map(struct depmod *depmod, const char *filename)
2348{
2349 const char ksymstr[] = "__ksymtab_";
2350 const size_t ksymstr_len = sizeof(ksymstr) - 1;
2351 char line[10240];
2352 FILE *fp;
2353 unsigned int linenum = 0;
4a0e46da
GSB
2354
2355 fp = fopen(filename, "r");
035cbdc7
KR
2356 if (fp == NULL) {
2357 int err = -errno;
2358 DBG("load System.map: %s: %m\n", filename);
4a0e46da 2359 return err;
035cbdc7
KR
2360 }
2361 DBG("load System.map: %s\n", filename);
4a0e46da
GSB
2362
2363 /* eg. c0294200 R __ksymtab_devfs_alloc_devnum */
2364 while (fgets(line, sizeof(line), fp) != NULL) {
2365 char *p, *end;
2366
2367 linenum++;
2368
2369 p = strchr(line, ' ');
2370 if (p == NULL)
2371 goto invalid_syntax;
2372 p++;
2373 p = strchr(p, ' ');
2374 if (p == NULL)
2375 goto invalid_syntax;
2376 p++;
2377
2378 /* Covers gpl-only and normal symbols. */
2379 if (strncmp(p, ksymstr, ksymstr_len) != 0)
2380 continue;
2381
2382 end = strchr(p, '\n');
2383 if (end != NULL)
2384 *end = '\0';
2385
2386 depmod_symbol_add(depmod, p + ksymstr_len, 0, NULL);
2387 continue;
2388
2389 invalid_syntax:
2390 ERR("%s:%u: invalid line: %s\n", filename, linenum, line);
2391 }
2392 depmod_add_fake_syms(depmod);
2393
035cbdc7 2394 DBG("loaded System.map: %s\n", filename);
4a0e46da
GSB
2395
2396 fclose(fp);
035cbdc7 2397 return 0;
4a0e46da 2398}
25c41512 2399
18cd9da3
GSB
2400
2401static int depfile_up_to_date_dir(DIR *d, time_t mtime, size_t baselen, char *path)
2402{
2403 struct dirent *de;
2404 int err = 1, dfd = dirfd(d);
2405
2406 while ((de = readdir(d)) != NULL) {
2407 const char *name = de->d_name;
2408 size_t namelen;
2409 struct stat st;
2410
2411 if (name[0] == '.' && (name[1] == '\0' ||
2412 (name[1] == '.' && name[2] == '\0')))
2413 continue;
2414 if (streq(name, "build") || streq(name, "source"))
2415 continue;
2416 namelen = strlen(name);
2417 if (baselen + namelen + 2 >= PATH_MAX) {
2418 path[baselen] = '\0';
2419 ERR("path is too long %s%s %zd\n", path, name);
2420 continue;
2421 }
2422
2423 if (fstatat(dfd, name, &st, 0) < 0) {
2424 ERR("fstatat(%d, %s): %m\n", dfd, name);
2425 continue;
2426 }
2427
2428 if (S_ISDIR(st.st_mode)) {
2429 int fd;
2430 DIR *subdir;
2431 memcpy(path + baselen, name, namelen + 1);
2432 if (baselen + namelen + 2 + NAME_MAX >= PATH_MAX) {
2433 ERR("directory path is too long %s\n", path);
2434 continue;
2435 }
2436 fd = openat(dfd, name, O_RDONLY);
2437 if (fd < 0) {
2438 ERR("openat(%d, %s, O_RDONLY): %m\n",
2439 dfd, name);
2440 continue;
2441 }
2442 subdir = fdopendir(fd);
2443 if (subdir == NULL) {
2444 ERR("fdopendir(%d): %m\n", fd);
2445 close(fd);
2446 continue;
2447 }
2448 path[baselen + namelen] = '/';
2449 path[baselen + namelen + 1] = '\0';
2450 err = depfile_up_to_date_dir(subdir, mtime,
2451 baselen + namelen + 1,
2452 path);
2453 closedir(subdir);
2454 } else if (S_ISREG(st.st_mode)) {
a627c3f3 2455 const struct kmod_ext *eitr;
18cd9da3 2456 uint8_t matches = 0;
a627c3f3 2457 for (eitr = kmod_exts; eitr->ext != NULL; eitr++) {
18cd9da3
GSB
2458 if (namelen <= eitr->len)
2459 continue;
2460 if (streq(name + namelen - eitr->len, eitr->ext)) {
2461 matches = 1;
2462 break;
2463 }
2464 }
2465 if (!matches)
2466 continue;
2467 memcpy(path + baselen, name, namelen + 1);
2468 err = st.st_mtime <= mtime;
2469 if (err == 0) {
2470 DBG("%s %"PRIu64" is newer than %"PRIu64"\n",
2471 path, (uint64_t)st.st_mtime,
2472 (uint64_t)mtime);
2473 }
2474 } else {
2475 ERR("unsupported file type %s: %o\n",
2476 path, st.st_mode & S_IFMT);
2477 continue;
2478 }
2479
2480 if (err == 0)
2481 break; /* outdated! */
2482 else if (err < 0) {
2483 path[baselen + namelen] = '\0';
2484 ERR("failed %s: %s\n", path, strerror(-err));
2485 err = 1; /* ignore errors */
2486 }
2487 }
2488
2489 return err;
2490}
2491
2492/* uptodate: 1, outdated: 0, errors < 0 */
64b8b586
GSB
2493static int depfile_up_to_date(const char *dirname)
2494{
18cd9da3
GSB
2495 char path[PATH_MAX];
2496 DIR *d = opendir(dirname);
2497 struct stat st;
2498 size_t baselen;
2499 int err;
2500 if (d == NULL) {
2501 err = -errno;
63698377 2502 ERR("could not open directory %s: %m\n", dirname);
18cd9da3
GSB
2503 return err;
2504 }
2505
2506 if (fstatat(dirfd(d), "modules.dep", &st, 0) != 0) {
2507 err = -errno;
63698377 2508 ERR("could not fstatat(%s, modules.dep): %m\n", dirname);
18cd9da3
GSB
2509 closedir(d);
2510 return err;
2511 }
2512
2513 baselen = strlen(dirname);
2514 memcpy(path, dirname, baselen);
2515 path[baselen] = '/';
2516 baselen++;
2517 path[baselen] = '\0';
2518
2519 err = depfile_up_to_date_dir(d, st.st_mtime, baselen, path);
2520 closedir(d);
2521 return err;
64b8b586
GSB
2522}
2523
2524static int is_version_number(const char *version)
2525{
2526 unsigned int d1, d2;
2527 return (sscanf(version, "%u.%u", &d1, &d2) == 2);
2528}
2529
f6cf14ce 2530static int do_depmod(int argc, char *argv[])
64b8b586
GSB
2531{
2532 FILE *out = NULL;
31f1d0d3 2533 int err = 0, all = 0, maybe_all = 0, n_config_paths = 0;
e15a56af 2534 char *root = NULL;
64b8b586 2535 const char **config_paths = NULL;
64b8b586
GSB
2536 const char *system_map = NULL;
2537 const char *module_symvers = NULL;
2538 const char *null_kmod_config = NULL;
2539 struct utsname un;
2540 struct kmod_ctx *ctx = NULL;
2541 struct cfg cfg;
2542 struct depmod depmod;
2543
2544 memset(&cfg, 0, sizeof(cfg));
2545 memset(&depmod, 0, sizeof(depmod));
2546
2547 for (;;) {
2548 int c, idx = 0;
2549 c = getopt_long(argc, argv, cmdopts_s, cmdopts, &idx);
2550 if (c == -1)
2551 break;
2552 switch (c) {
2553 case 'a':
2554 all = 1;
2555 break;
2556 case 'A':
2557 maybe_all = 1;
2558 break;
2559 case 'b':
e15a56af 2560 root = path_make_absolute_cwd(optarg);
64b8b586
GSB
2561 break;
2562 case 'C': {
2563 size_t bytes = sizeof(char *) * (n_config_paths + 2);
2564 void *tmp = realloc(config_paths, bytes);
2565 if (!tmp) {
2566 fputs("Error: out-of-memory\n", stderr);
2567 goto cmdline_failed;
2568 }
2569 config_paths = tmp;
2570 config_paths[n_config_paths] = optarg;
2571 n_config_paths++;
2572 config_paths[n_config_paths] = NULL;
2573 break;
2574 }
2575 case 'E':
2576 module_symvers = optarg;
2577 cfg.check_symvers = 1;
2578 break;
2579 case 'F':
2580 system_map = optarg;
2581 break;
2582 case 'e':
2583 cfg.print_unknown = 1;
2584 break;
2585 case 'v':
2586 verbose++;
2587 break;
2588 case 'n':
2589 out = stdout;
2590 break;
2591 case 'P':
2592 if (optarg[1] != '\0') {
2593 CRIT("-P only takes a single char\n");
2594 goto cmdline_failed;
2595 }
2596 cfg.sym_prefix = optarg[0];
2597 break;
2598 case 'w':
2599 cfg.warn_dups = 1;
2600 break;
2601 case 'u':
2602 case 'q':
2603 case 'r':
2604 case 'm':
2605 if (idx > 0) {
2606 fprintf(stderr,
2607 "ignored deprecated option --%s\n",
2608 cmdopts[idx].name);
2609 } else {
2610 fprintf(stderr,
2611 "ignored deprecated option -%c\n", c);
2612 }
2613 break;
2614 case 'h':
aa156c98 2615 help(basename(argv[0]));
64b8b586
GSB
2616 free(config_paths);
2617 return EXIT_SUCCESS;
2618 case 'V':
2619 puts(PACKAGE " version " VERSION);
2620 free(config_paths);
2621 return EXIT_SUCCESS;
2622 case '?':
2623 goto cmdline_failed;
2624 default:
2625 fprintf(stderr,
2626 "Error: unexpected getopt_long() value '%c'.\n",
2627 c);
2628 goto cmdline_failed;
2629 }
2630 }
2631
2632 if (optind < argc && is_version_number(argv[optind])) {
2633 cfg.kversion = argv[optind];
2634 optind++;
2635 } else {
2636 if (uname(&un) < 0) {
2637 CRIT("uname() failed: %s\n", strerror(errno));
2638 goto cmdline_failed;
2639 }
2640 cfg.kversion = un.release;
2641 }
2642
2643 cfg.dirnamelen = snprintf(cfg.dirname, PATH_MAX,
2644 "%s" ROOTPREFIX "/lib/modules/%s",
e15a56af 2645 root == NULL ? "" : root, cfg.kversion);
64b8b586
GSB
2646
2647 if (optind == argc)
2648 all = 1;
2649
2650 if (maybe_all) {
2651 if (out == stdout)
2652 goto done;
18cd9da3
GSB
2653 /* ignore up-to-date errors (< 0) */
2654 if (depfile_up_to_date(cfg.dirname) == 1) {
2655 DBG("%s/modules.dep is up to date!\n", cfg.dirname);
64b8b586 2656 goto done;
18cd9da3
GSB
2657 }
2658 DBG("%s/modules.dep is outdated, do -a\n", cfg.dirname);
64b8b586
GSB
2659 all = 1;
2660 }
2661
2662 ctx = kmod_new(cfg.dirname, &null_kmod_config);
2663 if (ctx == NULL) {
2664 CRIT("kmod_new(\"%s\", {NULL}) failed: %m\n", cfg.dirname);
2665 goto cmdline_failed;
2666 }
2667 kmod_set_log_priority(ctx, verbose);
2668
2669 err = depmod_init(&depmod, &cfg, ctx);
2670 if (err < 0) {
2671 CRIT("depmod_init: %s\n", strerror(-err));
2672 goto depmod_init_failed;
2673 }
2674 ctx = NULL; /* owned by depmod */
2675
4a0e46da
GSB
2676 if (module_symvers != NULL) {
2677 err = depmod_load_symvers(&depmod, module_symvers);
2678 if (err < 0) {
63698377 2679 CRIT("could not load %s: %s\n", module_symvers,
4a0e46da
GSB
2680 strerror(-err));
2681 goto cmdline_failed;
2682 }
2683 } else if (system_map != NULL) {
2684 err = depmod_load_system_map(&depmod, system_map);
2685 if (err < 0) {
035cbdc7 2686 CRIT("could not load %s: %s\n", system_map,
4a0e46da
GSB
2687 strerror(-err));
2688 goto cmdline_failed;
2689 }
2690 } else if (cfg.print_unknown) {
2691 WRN("-e needs -E or -F\n");
2692 cfg.print_unknown = 0;
2693 }
2694
64b8b586
GSB
2695 if (all) {
2696 err = cfg_load(&cfg, config_paths);
2697 if (err < 0) {
63698377 2698 CRIT("could not load configuration files\n");
64b8b586
GSB
2699 goto cmdline_modules_failed;
2700 }
2701 err = depmod_modules_search(&depmod);
2702 if (err < 0) {
63698377 2703 CRIT("could not search modules: %s\n", strerror(-err));
64b8b586
GSB
2704 goto cmdline_modules_failed;
2705 }
2706 } else {
31f1d0d3
LDM
2707 int i;
2708
64b8b586
GSB
2709 for (i = optind; i < argc; i++) {
2710 const char *path = argv[i];
2711 struct kmod_module *mod;
2712
2713 if (path[0] != '/') {
b0bcadd0 2714 CRIT("%s: not absolute path.\n", path);
64b8b586
GSB
2715 goto cmdline_modules_failed;
2716 }
2717
2718 err = kmod_module_new_from_path(depmod.ctx, path, &mod);
2719 if (err < 0) {
63698377 2720 CRIT("could not create module %s: %s\n",
64b8b586
GSB
2721 path, strerror(-err));
2722 goto cmdline_modules_failed;
2723 }
2724
2725 err = depmod_module_add(&depmod, mod);
2726 if (err < 0) {
63698377 2727 CRIT("could not add module %s: %s\n",
64b8b586
GSB
2728 path, strerror(-err));
2729 kmod_module_unref(mod);
2730 goto cmdline_modules_failed;
2731 }
2732 }
2733 }
2734
00bd3191
JAS
2735 err = depmod_modules_build_array(&depmod);
2736 if (err < 0) {
2737 CRIT("could not build module array: %s\n",
2738 strerror(-err));
2739 goto cmdline_modules_failed;
2740 }
2741
64b8b586
GSB
2742 depmod_modules_sort(&depmod);
2743 err = depmod_load(&depmod);
2744 if (err < 0)
2745 goto cmdline_modules_failed;
2746
25c41512 2747 err = depmod_output(&depmod, out);
64b8b586
GSB
2748
2749done:
2750 depmod_shutdown(&depmod);
2751 cfg_free(&cfg);
2752 free(config_paths);
2753 return err >= 0 ? EXIT_SUCCESS : EXIT_FAILURE;
2754
2755cmdline_modules_failed:
2756 depmod_shutdown(&depmod);
2757depmod_init_failed:
2758 if (ctx != NULL)
2759 kmod_unref(ctx);
2760cmdline_failed:
2761 cfg_free(&cfg);
2762 free(config_paths);
e15a56af 2763 free(root);
64b8b586
GSB
2764 return EXIT_FAILURE;
2765}
f6cf14ce 2766
f6cf14ce
LDM
2767#include "kmod.h"
2768
2769const struct kmod_cmd kmod_cmd_compat_depmod = {
2770 .name = "depmod",
2771 .cmd = do_depmod,
2772 .help = "compat depmod command",
2773};