2 * kmod-depmod - calculate modules.dep using libkmod.
4 * Copyright (C) 2011-2012 ProFUSION embedded systems
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.
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.
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/>.
20 #include "libkmod-array.h"
21 #include "libkmod-hash.h"
22 #include "libkmod-util.h"
31 #include <sys/utsname.h>
40 #define DEFAULT_VERBOSE LOG_WARNING
41 static int verbose
= DEFAULT_VERBOSE
;
43 #define KMOD_EXT_UNC 0
45 static const struct kmod_ext
{
49 {".ko", sizeof(".ko") - 1},
51 {".ko.gz", sizeof(".ko.gz") - 1},
54 {".ko.xz", sizeof(".ko.xz") - 1},
59 static const char CFG_BUILTIN_KEY
[] = "built-in";
60 static const char *default_cfg_paths
[] = {
62 SYSCONFDIR
"/depmod.d",
67 static const char cmdopts_s
[] = "aAb:C:E:F:euqrvnP:wmVh";
68 static const struct option cmdopts
[] = {
69 { "all", no_argument
, 0, 'a' },
70 { "quick", no_argument
, 0, 'A' },
71 { "basedir", required_argument
, 0, 'b' },
72 { "config", required_argument
, 0, 'C' },
73 { "symvers", required_argument
, 0, 'E' },
74 { "filesyms", required_argument
, 0, 'F' },
75 { "errsyms", no_argument
, 0, 'e' },
76 { "unresolved-error", no_argument
, 0, 'u' }, /* deprecated */
77 { "quiet", no_argument
, 0, 'q' }, /* deprecated */
78 { "root", no_argument
, 0, 'r' }, /* deprecated */
79 { "verbose", no_argument
, 0, 'v' },
80 { "show", no_argument
, 0, 'n' },
81 { "dry-run", no_argument
, 0, 'n' },
82 { "symbol-prefix", no_argument
, 0, 'P' },
83 { "warn", no_argument
, 0, 'w' },
84 { "map", no_argument
, 0, 'm' }, /* deprecated */
85 { "version", no_argument
, 0, 'V' },
86 { "help", no_argument
, 0, 'h' },
90 static void help(void)
93 "\t%s -[aA] [options] [forced_version]\n"
95 "If no arguments (except options) are given, \"depmod -a\" is assumed\n"
97 "depmod will output a dependency list suitable for the modprobe utility.\n"
100 "\t-a, --all Probe all modules\n"
101 "\t-A, --quick Only does the work if there's a new module\n"
102 "\t-e, --errsyms Report not supplied symbols\n"
103 "\t-n, --show Write the dependency file on stdout only\n"
104 "\t-P, --symbol-prefix Architecture symbol prefix\n"
105 "\t-C, --config=PATH Read configuration from PATH\n"
106 "\t-v, --verbose Enable verbose mode\n"
107 "\t-w, --warn Warn on duplicates\n"
108 "\t-V, --version show version\n"
109 "\t-h, --help show this help\n"
111 "The following options are useful for people managing distributions:\n"
112 "\t-b, --basedir=DIR Use an image of a module tree.\n"
113 "\t-F, --filesyms=FILE Use the file instead of the\n"
114 "\t current kernel symbols.\n"
115 "\t-E, --symvers=FILE Use Module.symvers file to check\n"
116 "\t symbol versions.\n",
120 static inline void _show(const char *fmt
, ...)
124 if (verbose
<= DEFAULT_VERBOSE
)
128 vfprintf(stdout
, fmt
, args
);
133 static void _log(int prio
, const char *fmt
, ...)
135 const char *prioname
;
143 if (vasprintf(&msg
, fmt
, args
) < 0)
157 prioname
= "WARNING";
169 snprintf(buf
, sizeof(buf
), "LOG-%03d", prio
);
173 fprintf(stderr
, "depmod: %s: %s", prioname
, msg
);
176 if (prio
<= LOG_CRIT
)
179 #define CRIT(...) _log(LOG_CRIT, __VA_ARGS__)
180 #define ERR(...) _log(LOG_ERR, __VA_ARGS__)
181 #define WRN(...) _log(LOG_WARNING, __VA_ARGS__)
182 #define INF(...) _log(LOG_INFO, __VA_ARGS__)
183 #define DBG(...) _log(LOG_DEBUG, __VA_ARGS__)
184 #define SHOW(...) _show(__VA_ARGS__)
187 /* binary index write *************************************************/
188 #include <arpa/inet.h>
190 /* BEGIN: code from module-init-tools/index.c just modified to compile here.
192 * Original copyright:
193 * index.c: module index file shared functions for modprobe and depmod
194 * Copyright (C) 2008 Alan Jenkins <alan-jenkins@tuffmail.co.uk>.
196 * These programs are free software; you can redistribute it and/or modify
197 * it under the terms of the GNU General Public License as published by
198 * the Free Software Foundation; either version 2 of the License, or
199 * (at your option) any later version.
201 * This program is distributed in the hope that it will be useful,
202 * but WITHOUT ANY WARRANTY; without even the implied warranty of
203 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
204 * GNU General Public License for more details.
206 * You should have received a copy of the GNU General Public License
207 * along with these programs. If not, see <http://www.gnu.org/licenses/>.
210 /* Integers are stored as 32 bit unsigned in "network" order, i.e. MSB first.
211 All files start with a magic number.
213 Magic spells "BOOTFAST". Second one used on newer versioned binary files.
215 /* #define INDEX_MAGIC_OLD 0xB007FA57 */
216 #define INDEX_MAGIC 0xB007F457
218 /* We use a version string to keep track of changes to the binary format
219 * This is stored in the form: INDEX_MAJOR (hi) INDEX_MINOR (lo) just in
220 * case we ever decide to have minor changes that are not incompatible.
223 #define INDEX_VERSION_MAJOR 0x0002
224 #define INDEX_VERSION_MINOR 0x0001
225 #define INDEX_VERSION ((INDEX_VERSION_MAJOR<<16)|INDEX_VERSION_MINOR)
227 /* The index file maps keys to values. Both keys and values are ASCII strings.
228 Each key can have multiple values. Values are sorted by an integer priority.
230 The reader also implements a wildcard search (including range expressions)
231 where the keys in the index are treated as patterns.
232 This feature is required for module aliases.
235 /* Implementation is based on a radix tree, or "trie".
236 Each arc from parent to child is labelled with a character.
237 Each path from the root represents a string.
239 == Example strings ==
249 * Marked node, representing a key and it's values.
260 Naive implementations tend to be very space inefficient; child pointers
261 are stored in arrays indexed by character, but most child pointers are null.
263 Our implementation uses a scheme described by Wikipedia as a Patrica trie,
265 "easiest to understand as a space-optimized trie where
266 each node with only one child is merged with its child"
277 We still use arrays of child pointers indexed by a single character;
278 the remaining characters of the label are stored as a "prefix" in the child.
280 The paper describing the original Patrica trie works on individiual bits -
281 each node has a maximum of two children, which increases space efficiency.
282 However for this application it is simpler to use the ASCII character set.
283 Since the index file is read-only, it can be compressed by omitting null
284 child pointers at the start and end of arrays.
287 #define INDEX_PRIORITY_MIN UINT32_MAX
290 struct index_value
*next
;
291 unsigned int priority
;
295 /* In-memory index (depmod only) */
297 #define INDEX_CHILDMAX 128
299 char *prefix
; /* path compression */
300 struct index_value
*values
;
301 unsigned char first
; /* range of child nodes */
303 struct index_node
*children
[INDEX_CHILDMAX
]; /* indexed by character */
308 uint32_t magic = INDEX_MAGIC;
309 uint32_t version = INDEX_VERSION;
310 uint32_t root_offset;
312 (node_offset & INDEX_NODE_MASK) specifies the file offset of nodes:
314 char[] prefix; // nul terminated
318 uint32_t children[last - first + 1];
320 uint32_t value_count;
323 char[] value; // nul terminated
324 } values[value_count];
326 (node_offset & INDEX_NODE_FLAGS) indicates which fields are present.
327 Empty prefixes are omitted, leaf nodes omit the three child-related fields.
329 This could be optimised further by adding a sparse child format
330 (indicated using a new flag).
333 /* Format of node offsets within index file */
335 INDEX_NODE_FLAGS
= 0xF0000000, /* Flags in high nibble */
336 INDEX_NODE_PREFIX
= 0x80000000,
337 INDEX_NODE_VALUES
= 0x40000000,
338 INDEX_NODE_CHILDS
= 0x20000000,
340 INDEX_NODE_MASK
= 0x0FFFFFFF, /* Offset value */
343 static struct index_node
*index_create(void)
345 struct index_node
*node
;
347 node
= NOFAIL(calloc(sizeof(struct index_node
), 1));
348 node
->prefix
= NOFAIL(strdup(""));
349 node
->first
= INDEX_CHILDMAX
;
354 static void index_values_free(struct index_value
*values
)
357 struct index_value
*value
= values
;
359 values
= value
->next
;
364 static void index_destroy(struct index_node
*node
)
368 for (c
= node
->first
; c
<= node
->last
; c
++) {
369 struct index_node
*child
= node
->children
[c
];
372 index_destroy(child
);
374 index_values_free(node
->values
);
379 static void index__checkstring(const char *str
)
383 for (i
= 0; str
[i
]; i
++) {
386 if (ch
>= INDEX_CHILDMAX
)
387 CRIT("Module index: bad character '%c'=0x%x - only 7-bit ASCII is supported:"
388 "\n%s\n", (char) ch
, (int) ch
, str
);
392 static int index_add_value(struct index_value
**values
,
393 const char *value
, unsigned int priority
)
395 struct index_value
*v
;
399 /* report the presence of duplicate values */
400 for (v
= *values
; v
; v
= v
->next
) {
401 if (streq(v
->value
, value
))
405 /* find position to insert value */
406 while (*values
&& (*values
)->priority
< priority
)
407 values
= &(*values
)->next
;
410 v
= NOFAIL(calloc(sizeof(struct index_value
) + len
+ 1, 1));
412 v
->priority
= priority
;
413 memcpy(v
->value
, value
, len
+ 1);
419 static int index_insert(struct index_node
*node
, const char *key
,
420 const char *value
, unsigned int priority
)
422 int i
= 0; /* index within str */
425 index__checkstring(key
);
426 index__checkstring(value
);
429 int j
; /* index within node->prefix */
431 /* Ensure node->prefix is a prefix of &str[i].
432 If it is not already, then we must split node. */
433 for (j
= 0; node
->prefix
[j
]; j
++) {
434 ch
= node
->prefix
[j
];
436 if (ch
!= key
[i
+j
]) {
437 char *prefix
= node
->prefix
;
438 struct index_node
*n
;
440 /* New child is copy of node with prefix[j+1..N] */
441 n
= NOFAIL(calloc(sizeof(struct index_node
), 1));
442 memcpy(n
, node
, sizeof(struct index_node
));
443 n
->prefix
= NOFAIL(strdup(&prefix
[j
+1]));
445 /* Parent has prefix[0..j], child at prefix[j] */
446 memset(node
, 0, sizeof(struct index_node
));
448 node
->prefix
= prefix
;
451 node
->children
[ch
] = n
;
456 /* j is now length of node->prefix */
461 return index_add_value(&node
->values
, value
, priority
);
463 if (!node
->children
[ch
]) {
464 struct index_node
*child
;
466 if (ch
< node
->first
)
470 node
->children
[ch
] = NOFAIL(calloc(sizeof(struct index_node
), 1));
472 child
= node
->children
[ch
];
473 child
->prefix
= NOFAIL(strdup(&key
[i
+1]));
474 child
->first
= INDEX_CHILDMAX
;
475 index_add_value(&child
->values
, value
, priority
);
480 /* Descend into child node and continue */
481 node
= node
->children
[ch
];
486 static int index__haschildren(const struct index_node
*node
)
488 return node
->first
< INDEX_CHILDMAX
;
491 /* Recursive post-order traversal
493 Pre-order would make for better read-side buffering / readahead / caching.
494 (post-order means you go backwards in the file as you descend the tree).
495 However, index reading is already fast enough.
496 Pre-order is simpler for writing, and depmod is already slow.
498 static uint32_t index_write__node(const struct index_node
*node
, FILE *out
)
500 uint32_t *child_offs
= NULL
;
507 /* Write children and save their offsets */
508 if (index__haschildren(node
)) {
509 const struct index_node
*child
;
512 child_count
= node
->last
- node
->first
+ 1;
513 child_offs
= NOFAIL(malloc(child_count
* sizeof(uint32_t)));
515 for (i
= 0; i
< child_count
; i
++) {
516 child
= node
->children
[node
->first
+ i
];
517 child_offs
[i
] = htonl(index_write__node(child
, out
));
521 /* Now write this node */
524 if (node
->prefix
[0]) {
525 fputs(node
->prefix
, out
);
527 offset
|= INDEX_NODE_PREFIX
;
531 fputc(node
->first
, out
);
532 fputc(node
->last
, out
);
533 fwrite(child_offs
, sizeof(uint32_t), child_count
, out
);
535 offset
|= INDEX_NODE_CHILDS
;
539 const struct index_value
*v
;
540 unsigned int value_count
;
544 for (v
= node
->values
; v
!= NULL
; v
= v
->next
)
546 u
= htonl(value_count
);
547 fwrite(&u
, sizeof(u
), 1, out
);
549 for (v
= node
->values
; v
!= NULL
; v
= v
->next
) {
550 u
= htonl(v
->priority
);
551 fwrite(&u
, sizeof(u
), 1, out
);
552 fputs(v
->value
, out
);
555 offset
|= INDEX_NODE_VALUES
;
561 static void index_write(const struct index_node
*node
, FILE *out
)
563 long initial_offset
, final_offset
;
566 u
= htonl(INDEX_MAGIC
);
567 fwrite(&u
, sizeof(u
), 1, out
);
568 u
= htonl(INDEX_VERSION
);
569 fwrite(&u
, sizeof(u
), 1, out
);
571 /* Second word is reserved for the offset of the root node */
572 initial_offset
= ftell(out
);
574 fwrite(&u
, sizeof(uint32_t), 1, out
);
577 u
= htonl(index_write__node(node
, out
));
579 /* Update first word */
580 final_offset
= ftell(out
);
581 fseek(out
, initial_offset
, SEEK_SET
);
582 fwrite(&u
, sizeof(uint32_t), 1, out
);
583 fseek(out
, final_offset
, SEEK_SET
);
586 /* END: code from module-init-tools/index.c just modified to compile here.
589 /* utils (variants of libkmod-utils.c) *********************************/
590 static const char *underscores2(const char *input
, char *output
, size_t outputlen
)
594 for (i
= 0; input
[i
] != '\0' && i
< outputlen
- 1; i
++) {
601 WRN("Unmatched bracket in %s\n", input
);
605 size_t off
= strcspn(input
+ i
, "]");
606 if (input
[i
+ off
] == '\0') {
607 WRN("Unmatched bracket in %s\n", input
);
610 memcpy(output
+ i
, input
+ i
, off
+ 1);
616 output
[i
] = input
[i
];
624 /* configuration parsing **********************************************/
625 struct cfg_override
{
626 struct cfg_override
*next
;
632 struct cfg_search
*next
;
639 const char *kversion
;
640 char dirname
[PATH_MAX
];
643 uint8_t check_symvers
;
644 uint8_t print_unknown
;
646 struct cfg_override
*overrides
;
647 struct cfg_search
*searches
;
650 static int cfg_search_add(struct cfg
*cfg
, const char *path
, uint8_t builtin
)
652 struct cfg_search
*s
;
658 len
= strlen(path
) + 1;
660 s
= malloc(sizeof(struct cfg_search
) + len
);
662 ERR("search add: out of memory\n");
665 s
->builtin
= builtin
;
670 memcpy(s
->path
, path
, len
);
673 DBG("search add: %s, builtin=%hhu\n", path
, builtin
);
675 s
->next
= cfg
->searches
;
680 static void cfg_search_free(struct cfg_search
*s
)
685 static int cfg_override_add(struct cfg
*cfg
, const char *modname
, const char *subdir
)
687 struct cfg_override
*o
;
688 size_t modnamelen
= strlen(modname
);
689 size_t subdirlen
= strlen(subdir
);
692 o
= malloc(sizeof(struct cfg_override
) + subdirlen
+ 1
695 ERR("override add: out of memory\n");
698 memcpy(o
->path
, subdir
, subdirlen
);
703 memcpy(o
->path
+ i
, modname
, modnamelen
);
705 o
->path
[i
] = '\0'; /* no extension, so we can match .ko/.ko.gz */
709 DBG("override add: %s\n", o
->path
);
711 o
->next
= cfg
->overrides
;
716 static void cfg_override_free(struct cfg_override
*o
)
721 static int cfg_kernel_matches(const struct cfg
*cfg
, const char *pattern
)
727 if (streq(pattern
, "*"))
730 if (regcomp(&re
, pattern
, REG_EXTENDED
|REG_NOSUB
) != 0)
733 status
= regexec(&re
, cfg
->kversion
, 0, NULL
, 0);
739 static int cfg_file_parse(struct cfg
*cfg
, const char *filename
)
743 unsigned int linenum
= 0;
746 fp
= fopen(filename
, "r");
749 ERR("file parse %s: %m\n", filename
);
753 while ((line
= getline_wrapped(fp
, &linenum
)) != NULL
) {
756 if (line
[0] == '\0' || line
[0] == '#')
759 cmd
= strtok_r(line
, "\t ", &saveptr
);
763 if (streq(cmd
, "search")) {
765 while ((sp
= strtok_r(NULL
, "\t ", &saveptr
)) != NULL
) {
766 uint8_t builtin
= streq(sp
, CFG_BUILTIN_KEY
);
767 cfg_search_add(cfg
, sp
, builtin
);
769 } else if (streq(cmd
, "override")) {
770 const char *modname
= strtok_r(NULL
, "\t ", &saveptr
);
771 const char *version
= strtok_r(NULL
, "\t ", &saveptr
);
772 const char *subdir
= strtok_r(NULL
, "\t ", &saveptr
);
774 if (modname
== NULL
|| version
== NULL
||
778 if (!cfg_kernel_matches(cfg
, version
)) {
779 INF("%s:%u: override kernel did not match %s\n",
780 filename
, linenum
, version
);
784 cfg_override_add(cfg
, modname
, subdir
);
785 } else if (streq(cmd
, "include")
786 || streq(cmd
, "make_map_files")) {
787 INF("%s:%u: command %s not implemented yet\n",
788 filename
, linenum
, cmd
);
791 ERR("%s:%u: ignoring bad line starting with '%s'\n",
792 filename
, linenum
, cmd
);
804 static int cfg_files_filter_out(DIR *d
, const char *dir
, const char *name
)
806 size_t len
= strlen(name
);
812 if (len
< 6 || !streq(name
+ len
- 5, ".conf")) {
813 INF("All cfg files need .conf: %s/%s\n", dir
, name
);
817 fstatat(dirfd(d
), name
, &st
, 0);
818 if (S_ISDIR(st
.st_mode
)) {
819 ERR("Directories inside directories are not supported: %s/%s\n",
834 static void cfg_file_free(struct cfg_file
*f
)
839 static int cfg_files_insert_sorted(struct cfg_file
***p_files
, size_t *p_n_files
,
840 const char *dir
, const char *name
)
842 struct cfg_file
**files
, *f
;
843 size_t i
, n_files
, namelen
, dirlen
;
846 dirlen
= strlen(dir
);
848 namelen
= strlen(name
);
850 name
= basename(dir
);
851 namelen
= strlen(name
);
852 dirlen
-= namelen
+ 1;
855 n_files
= *p_n_files
;
857 for (i
= 0; i
< n_files
; i
++) {
858 int cmp
= strcmp(name
, files
[i
]->name
);
860 DBG("Ignoring duplicate config file: %.*s/%s\n",
861 (int)dirlen
, dir
, name
);
867 f
= malloc(sizeof(struct cfg_file
) + dirlen
+ namelen
+ 2);
869 ERR("files insert sorted: out of memory\n");
873 tmp
= realloc(files
, sizeof(struct cfg_file
*) * (n_files
+ 1));
875 ERR("files insert sorted: out of memory\n");
879 *p_files
= files
= tmp
;
882 memmove(files
+ i
+ 1, files
+ i
,
883 sizeof(struct cfg_file
*) * (n_files
- i
));
888 f
->namelen
= namelen
;
889 f
->name
= f
->path
+ dirlen
+ 1;
890 memcpy(f
->path
, dir
, dirlen
);
891 f
->path
[dirlen
] = '/';
892 memcpy(f
->path
+ dirlen
+ 1, name
, namelen
);
893 f
->path
[dirlen
+ 1 + namelen
] = '\0';
895 *p_n_files
= n_files
+ 1;
900 * Insert configuration files ignoring duplicates
902 static int cfg_files_list(struct cfg_file
***p_files
, size_t *p_n_files
,
909 if (stat(path
, &st
) != 0) {
911 DBG("could not stat '%s': %m\n", path
);
915 if (S_ISREG(st
.st_mode
)) {
916 cfg_files_insert_sorted(p_files
, p_n_files
, path
, NULL
);
918 } if (!S_ISDIR(st
.st_mode
)) {
919 ERR("unsupported file mode %s: %#x\n", path
, st
.st_mode
);
925 ERR("files list %s: %m\n", path
);
930 struct dirent ent
, *entp
;
932 err
= readdir_r(d
, &ent
, &entp
);
934 ERR("reading entry %s\n", strerror(-err
));
939 if (cfg_files_filter_out(d
, path
, entp
->d_name
))
942 cfg_files_insert_sorted(p_files
, p_n_files
, path
, entp
->d_name
);
946 DBG("parsed configuration files from %s\n", path
);
950 static int cfg_load(struct cfg
*cfg
, const char * const *cfg_paths
)
952 size_t i
, n_files
= 0;
953 struct cfg_file
**files
= NULL
;
955 if (cfg_paths
== NULL
)
956 cfg_paths
= default_cfg_paths
;
958 for (i
= 0; cfg_paths
[i
] != NULL
; i
++)
959 cfg_files_list(&files
, &n_files
, cfg_paths
[i
]);
961 for (i
= 0; i
< n_files
; i
++) {
962 struct cfg_file
*f
= files
[i
];
963 cfg_file_parse(cfg
, f
->path
);
968 /* For backward compatibility add "updates" to the head of the search
969 * list here. But only if there was no "search" option specified.
971 if (cfg
->searches
== NULL
)
972 cfg_search_add(cfg
, "updates", 0);
977 static void cfg_free(struct cfg
*cfg
)
979 while (cfg
->overrides
) {
980 struct cfg_override
*tmp
= cfg
->overrides
;
981 cfg
->overrides
= cfg
->overrides
->next
;
982 cfg_override_free(tmp
);
985 while (cfg
->searches
) {
986 struct cfg_search
*tmp
= cfg
->searches
;
987 cfg
->searches
= cfg
->searches
->next
;
988 cfg_search_free(tmp
);
993 /* depmod calculations ***********************************************/
995 struct kmod_module
*kmod
;
997 const char *relpath
; /* path relative to '$ROOT/lib/modules/$VER/' */
998 char *uncrelpath
; /* same as relpath but ending in .ko */
999 struct kmod_list
*info_list
;
1000 struct kmod_list
*dep_sym_list
;
1001 struct array deps
; /* struct symbol */
1002 size_t baselen
; /* points to start of basename/filename */
1004 int sort_idx
; /* sort index using modules.order */
1005 int dep_sort_idx
; /* topological sort index */
1006 uint16_t idx
; /* index in depmod->modules.array */
1007 uint16_t users
; /* how many modules depend on this one */
1008 uint8_t dep_loop
: 1;
1019 const struct cfg
*cfg
;
1020 struct kmod_ctx
*ctx
;
1021 struct array modules
;
1022 struct hash
*modules_by_uncrelpath
;
1023 struct hash
*modules_by_name
;
1024 struct hash
*symbols
;
1025 unsigned int dep_loops
;
1028 static void mod_free(struct mod
*mod
)
1030 DBG("free %p kmod=%p, path=%s\n", mod
, mod
->kmod
, mod
->path
);
1031 array_free_array(&mod
->deps
);
1032 assert(mod
->kmod
== NULL
);
1033 kmod_module_info_free_list(mod
->info_list
);
1034 kmod_module_dependency_symbols_free_list(mod
->dep_sym_list
);
1035 free(mod
->uncrelpath
);
1040 static int mod_add_dependency(struct mod
*mod
, struct symbol
*sym
)
1044 DBG("%s depends on %s %s\n", mod
->path
, sym
->name
,
1045 sym
->owner
!= NULL
? sym
->owner
->path
: "(unknown)");
1047 if (sym
->owner
== NULL
)
1050 err
= array_append_unique(&mod
->deps
, sym
->owner
);
1056 sym
->owner
->users
++;
1057 SHOW("%s needs \"%s\": %s\n", mod
->path
, sym
->name
, sym
->owner
->path
);
1061 static void symbol_free(struct symbol
*sym
)
1063 DBG("free %p sym=%s, owner=%p %s\n", sym
, sym
->name
, sym
->owner
,
1064 sym
->owner
!= NULL
? sym
->owner
->path
: "");
1068 static int depmod_init(struct depmod
*depmod
, struct cfg
*cfg
,
1069 struct kmod_ctx
*ctx
)
1076 array_init(&depmod
->modules
, 128);
1078 depmod
->modules_by_uncrelpath
= hash_new(512, NULL
);
1079 if (depmod
->modules_by_uncrelpath
== NULL
) {
1081 goto modules_by_uncrelpath_failed
;
1084 depmod
->modules_by_name
= hash_new(512, NULL
);
1085 if (depmod
->modules_by_name
== NULL
) {
1087 goto modules_by_name_failed
;
1090 depmod
->symbols
= hash_new(2048, (void (*)(void *))symbol_free
);
1091 if (depmod
->symbols
== NULL
) {
1093 goto symbols_failed
;
1099 hash_free(depmod
->modules_by_name
);
1100 modules_by_name_failed
:
1101 hash_free(depmod
->modules_by_uncrelpath
);
1102 modules_by_uncrelpath_failed
:
1106 static void depmod_shutdown(struct depmod
*depmod
)
1110 hash_free(depmod
->symbols
);
1112 hash_free(depmod
->modules_by_uncrelpath
);
1114 hash_free(depmod
->modules_by_name
);
1116 for (i
= 0; i
< depmod
->modules
.count
; i
++)
1117 mod_free(depmod
->modules
.array
[i
]);
1118 array_free_array(&depmod
->modules
);
1120 kmod_unref(depmod
->ctx
);
1123 static int depmod_module_add(struct depmod
*depmod
, struct kmod_module
*kmod
)
1125 const struct cfg
*cfg
= depmod
->cfg
;
1126 const char *modname
, *lastslash
;
1131 modname
= kmod_module_get_name(kmod
);
1132 modnamelen
= strlen(modname
) + 1;
1134 mod
= calloc(1, sizeof(struct mod
) + modnamelen
);
1138 mod
->sort_idx
= depmod
->modules
.count
+ 1;
1139 mod
->dep_sort_idx
= INT32_MAX
;
1140 memcpy(mod
->modname
, modname
, modnamelen
);
1141 mod
->modnamelen
= modnamelen
;
1143 array_init(&mod
->deps
, 4);
1145 mod
->path
= strdup(kmod_module_get_path(kmod
));
1146 lastslash
= strrchr(mod
->path
, '/');
1147 mod
->baselen
= lastslash
- mod
->path
;
1148 if (strncmp(mod
->path
, cfg
->dirname
, cfg
->dirnamelen
) == 0 &&
1149 mod
->path
[cfg
->dirnamelen
] == '/')
1150 mod
->relpath
= mod
->path
+ cfg
->dirnamelen
+ 1;
1152 mod
->relpath
= NULL
;
1154 err
= hash_add_unique(depmod
->modules_by_name
, mod
->modname
, mod
);
1156 ERR("hash_add_unique %s: %s\n", mod
->modname
, strerror(-err
));
1160 if (mod
->relpath
!= NULL
) {
1161 size_t uncrelpathlen
= lastslash
- mod
->relpath
+ modnamelen
1162 + kmod_exts
[KMOD_EXT_UNC
].len
;
1163 mod
->uncrelpath
= memdup(mod
->relpath
, uncrelpathlen
+ 1);
1164 mod
->uncrelpath
[uncrelpathlen
] = '\0';
1165 err
= hash_add_unique(depmod
->modules_by_uncrelpath
,
1166 mod
->uncrelpath
, mod
);
1168 ERR("hash_add_unique %s: %s\n",
1169 mod
->relpath
, strerror(-err
));
1170 hash_del(depmod
->modules_by_name
, mod
->modname
);
1175 DBG("add %p kmod=%p, path=%s\n", mod
, kmod
, mod
->path
);
1180 free(mod
->uncrelpath
);
1185 static int depmod_module_del(struct depmod
*depmod
, struct mod
*mod
)
1187 DBG("del %p kmod=%p, path=%s\n", mod
, mod
->kmod
, mod
->path
);
1189 if (mod
->relpath
!= NULL
)
1190 hash_del(depmod
->modules_by_uncrelpath
, mod
->relpath
);
1192 hash_del(depmod
->modules_by_name
, mod
->modname
);
1198 /* returns if existing module @mod is higher priority than newpath.
1199 * note this is the inverse of module-init-tools is_higher_priority()
1201 static 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
)
1203 const struct cfg
*cfg
= depmod
->cfg
;
1204 const struct cfg_override
*ov
;
1205 const struct cfg_search
*se
;
1206 size_t newlen
= baselen
+ modnamelen
;
1207 size_t oldlen
= mod
->baselen
+ mod
->modnamelen
;
1208 const char *oldpath
= mod
->path
;
1209 int i
, bprio
= -1, oldprio
= -1, newprio
= -1;
1211 assert(strncmp(newpath
, cfg
->dirname
, cfg
->dirnamelen
) == 0);
1212 assert(strncmp(oldpath
, cfg
->dirname
, cfg
->dirnamelen
) == 0);
1214 newpath
+= cfg
->dirnamelen
+ 1;
1215 newlen
-= cfg
->dirnamelen
+ 1;
1216 oldpath
+= cfg
->dirnamelen
+ 1;
1217 oldlen
-= cfg
->dirnamelen
+ 1;
1219 DBG("comparing priorities of %s and %s\n",
1222 for (ov
= cfg
->overrides
; ov
!= NULL
; ov
= ov
->next
) {
1223 DBG("override %s\n", ov
->path
);
1224 if (newlen
== ov
->len
&& memcmp(ov
->path
, newpath
, newlen
) == 0)
1226 if (oldlen
== ov
->len
&& memcmp(ov
->path
, oldpath
, oldlen
) == 0)
1230 for (i
= 0, se
= cfg
->searches
; se
!= NULL
; se
= se
->next
, i
++) {
1231 DBG("search %s\n", se
->builtin
? "built-in" : se
->path
);
1234 else if (newlen
>= se
->len
&&
1235 memcmp(se
->path
, newpath
, se
->len
) == 0)
1237 else if (oldlen
>= se
->len
&&
1238 memcmp(se
->path
, oldpath
, se
->len
) == 0)
1247 DBG("priorities: built-in: %d, old: %d, new: %d\n",
1248 bprio
, newprio
, oldprio
);
1250 return newprio
<= oldprio
;
1253 static int depmod_modules_search_file(struct depmod
*depmod
, size_t baselen
, size_t namelen
, const char *path
)
1255 struct kmod_module
*kmod
;
1257 const char *relpath
;
1258 char modname
[PATH_MAX
];
1259 const struct kmod_ext
*eitr
;
1261 uint8_t matches
= 0;
1264 for (eitr
= kmod_exts
; eitr
->ext
!= NULL
; eitr
++) {
1265 if (namelen
<= eitr
->len
)
1267 if (streq(path
+ baselen
+ namelen
- eitr
->len
, eitr
->ext
)) {
1275 if (path_to_modname(path
, modname
, &modnamelen
) == NULL
) {
1276 ERR("could not get modname from path %s\n", path
);
1280 relpath
= path
+ depmod
->cfg
->dirnamelen
+ 1;
1281 DBG("try %s (%s)\n", relpath
, modname
);
1283 mod
= hash_find(depmod
->modules_by_name
, modname
);
1287 if (depmod_module_is_higher_priority(depmod
, mod
, baselen
,
1288 namelen
, modnamelen
, path
)) {
1289 DBG("Ignored lower priority: %s, higher: %s\n",
1294 DBG("Replace lower priority %s with new module %s\n",
1295 mod
->relpath
, relpath
);
1296 err
= depmod_module_del(depmod
, mod
);
1298 ERR("could not del module %s: %s\n", mod
->path
, strerror(-err
));
1303 err
= kmod_module_new_from_path(depmod
->ctx
, path
, &kmod
);
1305 ERR("could not create module %s: %s\n", path
, strerror(-err
));
1309 err
= depmod_module_add(depmod
, kmod
);
1311 ERR("could not add module %s: %s\n",
1312 path
, strerror(-err
));
1313 kmod_module_unref(kmod
);
1319 static int depmod_modules_search_dir(struct depmod
*depmod
, DIR *d
, size_t baselen
, char *path
)
1322 int err
= 0, dfd
= dirfd(d
);
1324 while ((de
= readdir(d
)) != NULL
) {
1325 const char *name
= de
->d_name
;
1329 if (name
[0] == '.' && (name
[1] == '\0' ||
1330 (name
[1] == '.' && name
[2] == '\0')))
1332 if (streq(name
, "build") || streq(name
, "source"))
1334 namelen
= strlen(name
);
1335 if (baselen
+ namelen
+ 2 >= PATH_MAX
) {
1336 path
[baselen
] = '\0';
1337 ERR("path is too long %s%s %zd\n", path
, name
);
1340 memcpy(path
+ baselen
, name
, namelen
+ 1);
1342 if (de
->d_type
== DT_REG
)
1344 else if (de
->d_type
== DT_DIR
)
1348 if (fstatat(dfd
, name
, &st
, 0) < 0) {
1349 ERR("fstatat(%d, %s): %m\n", dfd
, name
);
1351 } else if (S_ISREG(st
.st_mode
))
1353 else if (S_ISDIR(st
.st_mode
))
1356 ERR("unsupported file type %s: %o\n",
1357 path
, st
.st_mode
& S_IFMT
);
1365 if (baselen
+ namelen
+ 2 + NAME_MAX
>= PATH_MAX
) {
1366 ERR("directory path is too long %s\n", path
);
1369 fd
= openat(dfd
, name
, O_RDONLY
);
1371 ERR("openat(%d, %s, O_RDONLY): %m\n",
1375 subdir
= fdopendir(fd
);
1376 if (subdir
== NULL
) {
1377 ERR("fdopendir(%d): %m\n", fd
);
1381 path
[baselen
+ namelen
] = '/';
1382 path
[baselen
+ namelen
+ 1] = '\0';
1383 err
= depmod_modules_search_dir(depmod
, subdir
,
1384 baselen
+ namelen
+ 1,
1388 err
= depmod_modules_search_file(depmod
, baselen
,
1393 path
[baselen
+ namelen
] = '\0';
1394 ERR("failed %s: %s\n", path
, strerror(-err
));
1395 err
= 0; /* ignore errors */
1402 static int depmod_modules_search(struct depmod
*depmod
)
1404 char path
[PATH_MAX
];
1405 DIR *d
= opendir(depmod
->cfg
->dirname
);
1410 ERR("could not open directory %s: %m\n", depmod
->cfg
->dirname
);
1414 baselen
= depmod
->cfg
->dirnamelen
;
1415 memcpy(path
, depmod
->cfg
->dirname
, baselen
);
1416 path
[baselen
] = '/';
1418 path
[baselen
] = '\0';
1420 err
= depmod_modules_search_dir(depmod
, d
, baselen
, path
);
1425 static int mod_cmp(const void *pa
, const void *pb
) {
1426 const struct mod
*a
= *(const struct mod
**)pa
;
1427 const struct mod
*b
= *(const struct mod
**)pb
;
1428 if (a
->dep_loop
== b
->dep_loop
)
1429 return a
->sort_idx
- b
->sort_idx
;
1430 else if (a
->dep_loop
)
1432 else if (b
->dep_loop
)
1434 return a
->sort_idx
- b
->sort_idx
;
1437 static int depmod_modules_build_array(struct depmod
*depmod
)
1439 struct hash_iter module_iter
;
1443 hash_iter_init(depmod
->modules_by_name
, &module_iter
);
1444 while (hash_iter_next(&module_iter
, NULL
, &v
)) {
1445 struct mod
*mod
= (struct mod
*) v
;
1446 mod
->idx
= depmod
->modules
.count
;
1447 err
= array_append(&depmod
->modules
, mod
);
1455 static void depmod_modules_sort(struct depmod
*depmod
)
1457 char order_file
[PATH_MAX
], line
[PATH_MAX
];
1459 unsigned idx
= 0, total
= 0;
1461 snprintf(order_file
, sizeof(order_file
), "%s/modules.order",
1462 depmod
->cfg
->dirname
);
1463 fp
= fopen(order_file
, "r");
1465 WRN("could not open %s: %m\n", order_file
);
1469 while (fgets(line
, sizeof(line
), fp
) != NULL
) {
1470 size_t len
= strlen(line
);
1474 if (line
[len
- 1] != '\n') {
1475 ERR("%s:%u corrupted line misses '\\n'\n",
1482 fseek(fp
, 0, SEEK_SET
);
1483 while (fgets(line
, sizeof(line
), fp
) != NULL
) {
1484 size_t len
= strlen(line
);
1490 line
[len
- 1] = '\0';
1492 mod
= hash_find(depmod
->modules_by_uncrelpath
, line
);
1495 mod
->sort_idx
= idx
- total
;
1498 array_sort(&depmod
->modules
, mod_cmp
);
1499 for (idx
= 0; idx
< depmod
->modules
.count
; idx
++) {
1500 struct mod
*m
= depmod
->modules
.array
[idx
];
1508 static int depmod_symbol_add(struct depmod
*depmod
, const char *name
,
1509 uint64_t crc
, const struct mod
*owner
)
1515 if (name
[0] == depmod
->cfg
->sym_prefix
)
1518 namelen
= strlen(name
) + 1;
1519 sym
= malloc(sizeof(struct symbol
) + namelen
);
1523 sym
->owner
= (struct mod
*)owner
;
1525 memcpy(sym
->name
, name
, namelen
);
1527 err
= hash_add(depmod
->symbols
, sym
->name
, sym
);
1533 DBG("add %p sym=%s, owner=%p %s\n", sym
, sym
->name
, owner
,
1534 owner
!= NULL
? owner
->path
: "");
1539 static struct symbol
*depmod_symbol_find(const struct depmod
*depmod
,
1542 if (name
[0] == '.') /* PPC64 needs this: .foo == foo */
1544 if (name
[0] == depmod
->cfg
->sym_prefix
)
1546 return hash_find(depmod
->symbols
, name
);
1549 static int depmod_load_modules(struct depmod
*depmod
)
1551 struct mod
**itr
, **itr_end
;
1553 DBG("load symbols (%zd modules)\n", depmod
->modules
.count
);
1555 itr
= (struct mod
**)depmod
->modules
.array
;
1556 itr_end
= itr
+ depmod
->modules
.count
;
1557 for (; itr
< itr_end
; itr
++) {
1558 struct mod
*mod
= *itr
;
1559 struct kmod_list
*l
, *list
= NULL
;
1560 int err
= kmod_module_get_symbols(mod
->kmod
, &list
);
1563 DBG("ignoring %s: no symbols\n", mod
->path
);
1565 ERR("failed to load symbols from %s: %s\n",
1566 mod
->path
, strerror(-err
));
1569 kmod_list_foreach(l
, list
) {
1570 const char *name
= kmod_module_symbol_get_symbol(l
);
1571 uint64_t crc
= kmod_module_symbol_get_crc(l
);
1572 depmod_symbol_add(depmod
, name
, crc
, mod
);
1574 kmod_module_symbols_free_list(list
);
1577 kmod_module_get_info(mod
->kmod
, &mod
->info_list
);
1578 kmod_module_get_dependency_symbols(mod
->kmod
,
1579 &mod
->dep_sym_list
);
1580 kmod_module_unref(mod
->kmod
);
1584 DBG("loaded symbols (%zd modules, %zd symbols)\n",
1585 depmod
->modules
.count
, hash_get_count(depmod
->symbols
));
1590 static int depmod_load_module_dependencies(struct depmod
*depmod
, struct mod
*mod
)
1592 const struct cfg
*cfg
= depmod
->cfg
;
1593 struct kmod_list
*l
;
1595 DBG("do dependencies of %s\n", mod
->path
);
1596 kmod_list_foreach(l
, mod
->dep_sym_list
) {
1597 const char *name
= kmod_module_dependency_symbol_get_symbol(l
);
1598 uint64_t crc
= kmod_module_dependency_symbol_get_crc(l
);
1599 int bindtype
= kmod_module_dependency_symbol_get_bind(l
);
1600 struct symbol
*sym
= depmod_symbol_find(depmod
, name
);
1601 uint8_t is_weak
= bindtype
== KMOD_SYMBOL_WEAK
;
1604 DBG("%s needs (%c) unknown symbol %s\n",
1605 mod
->path
, bindtype
, name
);
1606 if (cfg
->print_unknown
&& !is_weak
)
1607 WRN("%s needs unknown symbol %s\n",
1612 if (cfg
->check_symvers
&& sym
->crc
!= crc
&& !is_weak
) {
1613 DBG("symbol %s (%#"PRIx64
") module %s (%#"PRIx64
")\n",
1614 sym
->name
, sym
->crc
, mod
->path
, crc
);
1615 if (cfg
->print_unknown
)
1616 WRN("%s disagrees about version of symbol %s\n",
1620 mod_add_dependency(mod
, sym
);
1626 static int depmod_load_dependencies(struct depmod
*depmod
)
1628 struct mod
**itr
, **itr_end
;
1630 DBG("load dependencies (%zd modules, %zd symbols)\n",
1631 depmod
->modules
.count
, hash_get_count(depmod
->symbols
));
1633 itr
= (struct mod
**)depmod
->modules
.array
;
1634 itr_end
= itr
+ depmod
->modules
.count
;
1635 for (; itr
< itr_end
; itr
++) {
1636 struct mod
*mod
= *itr
;
1638 if (mod
->dep_sym_list
== NULL
) {
1639 DBG("ignoring %s: no dependency symbols\n", mod
->path
);
1643 depmod_load_module_dependencies(depmod
, mod
);
1646 DBG("loaded dependencies (%zd modules, %zd symbols)\n",
1647 depmod
->modules
.count
, hash_get_count(depmod
->symbols
));
1652 static int dep_cmp(const void *pa
, const void *pb
)
1654 const struct mod
*a
= *(const struct mod
**)pa
;
1655 const struct mod
*b
= *(const struct mod
**)pb
;
1656 if (a
->dep_loop
== b
->dep_loop
)
1657 return a
->dep_sort_idx
- b
->dep_sort_idx
;
1658 else if (a
->dep_loop
)
1660 else if (b
->dep_loop
)
1662 return a
->dep_sort_idx
- b
->dep_sort_idx
;
1665 static void depmod_sort_dependencies(struct depmod
*depmod
)
1667 struct mod
**itr
, **itr_end
;
1668 itr
= (struct mod
**)depmod
->modules
.array
;
1669 itr_end
= itr
+ depmod
->modules
.count
;
1670 for (; itr
< itr_end
; itr
++) {
1671 struct mod
*m
= *itr
;
1672 if (m
->deps
.count
> 1)
1673 array_sort(&m
->deps
, dep_cmp
);
1677 static int depmod_calculate_dependencies(struct depmod
*depmod
)
1679 const struct mod
**itrm
;
1680 uint16_t *users
, *roots
, *sorted
;
1681 uint16_t i
, n_roots
= 0, n_sorted
= 0, n_mods
= depmod
->modules
.count
;
1683 users
= malloc(sizeof(uint16_t) * n_mods
* 3);
1686 roots
= users
+ n_mods
;
1687 sorted
= roots
+ n_mods
;
1689 DBG("calculate dependencies and ordering (%zd modules)\n", n_mods
);
1691 assert(depmod
->modules
.count
< UINT16_MAX
);
1693 /* populate modules users (how many modules uses it) */
1694 itrm
= (const struct mod
**)depmod
->modules
.array
;
1695 for (i
= 0; i
< n_mods
; i
++, itrm
++) {
1696 const struct mod
*m
= *itrm
;
1697 users
[i
] = m
->users
;
1698 if (users
[i
] == 0) {
1704 /* topological sort (outputs modules without users first) */
1705 while (n_roots
> 0) {
1706 const struct mod
**itr_dst
, **itr_dst_end
;
1708 uint16_t src_idx
= roots
[--n_roots
];
1710 src
= depmod
->modules
.array
[src_idx
];
1711 src
->dep_sort_idx
= n_sorted
;
1712 sorted
[n_sorted
] = src_idx
;
1715 itr_dst
= (const struct mod
**)src
->deps
.array
;
1716 itr_dst_end
= itr_dst
+ src
->deps
.count
;
1717 for (; itr_dst
< itr_dst_end
; itr_dst
++) {
1718 const struct mod
*dst
= *itr_dst
;
1719 uint16_t dst_idx
= dst
->idx
;
1720 assert(users
[dst_idx
] > 0);
1722 if (users
[dst_idx
] == 0) {
1723 roots
[n_roots
] = dst_idx
;
1729 if (n_sorted
< n_mods
) {
1730 WRN("found %hu modules in dependency cycles!\n",
1732 for (i
= 0; i
< n_mods
; i
++) {
1736 m
= depmod
->modules
.array
[i
];
1737 WRN("%s in dependency cycle!\n", m
->path
);
1739 m
->dep_sort_idx
= INT32_MAX
;
1740 depmod
->dep_loops
++;
1744 depmod_sort_dependencies(depmod
);
1746 DBG("calculated dependencies and ordering (%u loops, %zd modules)\n",
1747 depmod
->dep_loops
, n_mods
);
1753 static int depmod_load(struct depmod
*depmod
)
1757 err
= depmod_load_modules(depmod
);
1761 err
= depmod_load_dependencies(depmod
);
1765 err
= depmod_calculate_dependencies(depmod
);
1772 static size_t mod_count_all_dependencies(const struct mod
*mod
)
1774 size_t i
, count
= 0;
1775 for (i
= 0; i
< mod
->deps
.count
; i
++) {
1776 const struct mod
*d
= mod
->deps
.array
[i
];
1777 count
+= 1 + mod_count_all_dependencies(d
);
1782 static int mod_fill_all_unique_dependencies(const struct mod
*mod
, const struct mod
**deps
, size_t n_deps
, size_t *last
)
1786 for (i
= 0; i
< mod
->deps
.count
; i
++) {
1787 const struct mod
*d
= mod
->deps
.array
[i
];
1791 for (j
= 0; j
< *last
; j
++) {
1801 if (*last
>= n_deps
)
1805 err
= mod_fill_all_unique_dependencies(d
, deps
, n_deps
, last
);
1812 static const struct mod
**mod_get_all_sorted_dependencies(const struct mod
*mod
, size_t *n_deps
)
1814 const struct mod
**deps
;
1817 *n_deps
= mod_count_all_dependencies(mod
);
1821 deps
= malloc(sizeof(struct mod
*) * (*n_deps
));
1825 if (mod_fill_all_unique_dependencies(mod
, deps
, *n_deps
, &last
) < 0) {
1830 qsort(deps
, last
, sizeof(struct mod
*), dep_cmp
);
1835 static inline const char *mod_get_compressed_path(const struct mod
*mod
)
1837 if (mod
->relpath
!= NULL
)
1838 return mod
->relpath
;
1842 static int output_deps(struct depmod
*depmod
, FILE *out
)
1846 for (i
= 0; i
< depmod
->modules
.count
; i
++) {
1847 const struct mod
**deps
, *mod
= depmod
->modules
.array
[i
];
1848 const char *p
= mod_get_compressed_path(mod
);
1851 if (mod
->dep_loop
) {
1852 DBG("Ignored %s due dependency loops\n", p
);
1856 fprintf(out
, "%s:", p
);
1858 if (mod
->deps
.count
== 0)
1861 deps
= mod_get_all_sorted_dependencies(mod
, &n_deps
);
1863 ERR("could not get all sorted dependencies of %s\n", p
);
1867 for (j
= 0; j
< n_deps
; j
++) {
1868 const struct mod
*d
= deps
[j
];
1870 DBG("Ignored %s (dependency of %s) "
1871 "due dependency loops\n",
1872 mod_get_compressed_path(d
), p
);
1875 fprintf(out
, " %s", mod_get_compressed_path(d
));
1885 static int output_deps_bin(struct depmod
*depmod
, FILE *out
)
1887 struct index_node
*idx
;
1893 idx
= index_create();
1897 for (i
= 0; i
< depmod
->modules
.count
; i
++) {
1898 const struct mod
**deps
, *mod
= depmod
->modules
.array
[i
];
1899 const char *p
= mod_get_compressed_path(mod
);
1901 size_t j
, n_deps
, linepos
, linelen
, slen
;
1904 if (mod
->dep_loop
) {
1905 DBG("Ignored %s due dependency loops\n", p
);
1909 deps
= mod_get_all_sorted_dependencies(mod
, &n_deps
);
1910 if (deps
== NULL
&& n_deps
> 0) {
1911 ERR("could not get all sorted dependencies of %s\n", p
);
1915 linelen
= strlen(p
) + 1;
1916 for (j
= 0; j
< n_deps
; j
++) {
1917 const struct mod
*d
= deps
[j
];
1919 DBG("Ignored %s (dependency of %s) "
1920 "due dependency loops\n",
1921 mod_get_compressed_path(d
), p
);
1924 linelen
+= 1 + strlen(mod_get_compressed_path(d
));
1927 line
= malloc(linelen
+ 1);
1930 ERR("modules.deps.bin: out of memory\n");
1936 memcpy(line
+ linepos
, p
, slen
);
1938 line
[linepos
] = ':';
1941 for (j
= 0; j
< n_deps
; j
++) {
1942 const struct mod
*d
= deps
[j
];
1946 line
[linepos
] = ' ';
1949 dp
= mod_get_compressed_path(d
);
1951 memcpy(line
+ linepos
, dp
, slen
);
1954 line
[linepos
] = '\0';
1956 duplicate
= index_insert(idx
, mod
->modname
, line
, mod
->idx
);
1957 if (duplicate
&& depmod
->cfg
->warn_dups
)
1958 WRN("duplicate module deps:\n%s\n", line
);
1963 index_write(idx
, out
);
1969 static int output_aliases(struct depmod
*depmod
, FILE *out
)
1973 fputs("# Aliases extracted from modules themselves.\n", out
);
1975 for (i
= 0; i
< depmod
->modules
.count
; i
++) {
1976 const struct mod
*mod
= depmod
->modules
.array
[i
];
1977 struct kmod_list
*l
;
1979 kmod_list_foreach(l
, mod
->info_list
) {
1980 const char *key
= kmod_module_info_get_key(l
);
1981 const char *value
= kmod_module_info_get_value(l
);
1983 if (!streq(key
, "alias"))
1986 fprintf(out
, "alias %s %s\n", value
, mod
->modname
);
1993 static int output_aliases_bin(struct depmod
*depmod
, FILE *out
)
1996 struct index_node
*idx
;
2002 idx
= index_create();
2006 for (i
= 0; i
< depmod
->modules
.count
; i
++) {
2007 const struct mod
*mod
= depmod
->modules
.array
[i
];
2008 struct kmod_list
*l
;
2010 kmod_list_foreach(l
, mod
->info_list
) {
2011 const char *key
= kmod_module_info_get_key(l
);
2012 const char *value
= kmod_module_info_get_value(l
);
2016 if (!streq(key
, "alias"))
2019 alias
= underscores2(value
, buf
, sizeof(buf
));
2023 duplicate
= index_insert(idx
, alias
, mod
->modname
,
2025 if (duplicate
&& depmod
->cfg
->warn_dups
)
2026 WRN("duplicate module alias:\n%s %s\n",
2027 alias
, mod
->modname
);
2031 index_write(idx
, out
);
2037 static int output_softdeps(struct depmod
*depmod
, FILE *out
)
2041 fputs("# Soft dependencies extracted from modules themselves.\n", out
);
2042 fputs("# Copy, with a .conf extension, to /etc/modprobe.d to use "
2043 "it with modprobe.\n", out
);
2045 for (i
= 0; i
< depmod
->modules
.count
; i
++) {
2046 const struct mod
*mod
= depmod
->modules
.array
[i
];
2047 struct kmod_list
*l
;
2049 kmod_list_foreach(l
, mod
->info_list
) {
2050 const char *key
= kmod_module_info_get_key(l
);
2051 const char *value
= kmod_module_info_get_value(l
);
2053 if (!streq(key
, "softdep"))
2056 fprintf(out
, "softdep %s %s\n", mod
->modname
, value
);
2063 static int output_symbols(struct depmod
*depmod
, FILE *out
)
2065 struct hash_iter iter
;
2068 fputs("# Aliases for symbols, used by symbol_request().\n", out
);
2070 hash_iter_init(depmod
->symbols
, &iter
);
2072 while (hash_iter_next(&iter
, NULL
, &v
)) {
2073 const struct symbol
*sym
= v
;
2074 if (sym
->owner
== NULL
)
2077 fprintf(out
, "alias symbol:%s %s\n",
2078 sym
->name
, sym
->owner
->modname
);
2084 static int output_symbols_bin(struct depmod
*depmod
, FILE *out
)
2086 struct index_node
*idx
;
2088 size_t baselen
= sizeof("symbol:") - 1;
2089 struct hash_iter iter
;
2095 idx
= index_create();
2099 memcpy(alias
, "symbol:", baselen
);
2100 hash_iter_init(depmod
->symbols
, &iter
);
2102 while (hash_iter_next(&iter
, NULL
, &v
)) {
2104 const struct symbol
*sym
= v
;
2106 if (sym
->owner
== NULL
)
2109 strcpy(alias
+ baselen
, sym
->name
);
2110 duplicate
= index_insert(idx
, alias
, sym
->owner
->modname
,
2113 if (duplicate
&& depmod
->cfg
->warn_dups
)
2114 WRN("duplicate module syms:\n%s %s\n",
2115 alias
, sym
->owner
->modname
);
2118 index_write(idx
, out
);
2124 static int output_builtin_bin(struct depmod
*depmod
, FILE *out
)
2127 struct index_node
*idx
;
2128 char infile
[PATH_MAX
], line
[PATH_MAX
], modname
[PATH_MAX
];
2133 snprintf(infile
, sizeof(infile
), "%s/modules.builtin",
2134 depmod
->cfg
->dirname
);
2135 in
= fopen(infile
, "r");
2137 WRN("could not open %s: %m\n", infile
);
2141 idx
= index_create();
2147 while (fgets(line
, sizeof(line
), in
) != NULL
) {
2148 if (!isalpha(line
[0])) {
2149 ERR("Invalid modules.builtin line: %s\n", line
);
2153 path_to_modname(line
, modname
, NULL
);
2154 index_insert(idx
, modname
, "", 0);
2157 index_write(idx
, out
);
2164 static int output_devname(struct depmod
*depmod
, FILE *out
)
2168 fputs("# Device nodes to trigger on-demand module loading.\n", out
);
2170 for (i
= 0; i
< depmod
->modules
.count
; i
++) {
2171 const struct mod
*mod
= depmod
->modules
.array
[i
];
2172 struct kmod_list
*l
;
2173 const char *devname
= NULL
;
2175 unsigned int major
= 0, minor
= 0;
2177 kmod_list_foreach(l
, mod
->info_list
) {
2178 const char *key
= kmod_module_info_get_key(l
);
2179 const char *value
= kmod_module_info_get_value(l
);
2180 unsigned int maj
, min
;
2182 if (!streq(key
, "alias"))
2185 if (strstartswith(value
, "devname:"))
2186 devname
= value
+ sizeof("devname:") - 1;
2187 else if (sscanf(value
, "char-major-%u-%u",
2192 } else if (sscanf(value
, "block-major-%u-%u",
2199 if (type
!= '\0' && devname
!= NULL
) {
2200 fprintf(out
, "%s %s %c%u:%u\n", mod
->modname
,
2201 devname
, type
, major
, minor
);
2210 static int depmod_output(struct depmod
*depmod
, FILE *out
)
2212 static const struct depfile
{
2214 int (*cb
)(struct depmod
*depmod
, FILE *out
);
2215 } *itr
, depfiles
[] = {
2216 { "modules.dep", output_deps
},
2217 { "modules.dep.bin", output_deps_bin
},
2218 { "modules.alias", output_aliases
},
2219 { "modules.alias.bin", output_aliases_bin
},
2220 { "modules.softdep", output_softdeps
},
2221 { "modules.symbols", output_symbols
},
2222 { "modules.symbols.bin", output_symbols_bin
},
2223 { "modules.builtin.bin", output_builtin_bin
},
2224 { "modules.devname", output_devname
},
2227 const char *dname
= depmod
->cfg
->dirname
;
2233 dfd
= open(dname
, O_RDONLY
);
2236 CRIT("could not open directory %s: %m\n", dname
);
2241 for (itr
= depfiles
; itr
->name
!= NULL
; itr
++) {
2243 char tmp
[NAME_MAX
] = "";
2247 int flags
= O_CREAT
| O_TRUNC
| O_WRONLY
;
2251 snprintf(tmp
, sizeof(tmp
), "%s.tmp", itr
->name
);
2252 fd
= openat(dfd
, tmp
, flags
, mode
);
2254 ERR("openat(%s, %s, %o, %o): %m\n",
2255 dname
, tmp
, flags
, mode
);
2258 fp
= fdopen(fd
, "wb");
2260 ERR("fdopen(%d=%s/%s): %m\n", fd
, dname
, tmp
);
2266 r
= itr
->cb(depmod
, fp
);
2270 ferr
= ferror(fp
) | fclose(fp
);
2273 if (unlinkat(dfd
, tmp
, 0) != 0)
2274 ERR("unlinkat(%s, %s): %m\n", dname
, tmp
);
2276 ERR("Could not write index '%s': %s\n", itr
->name
,
2282 unlinkat(dfd
, itr
->name
, 0);
2283 if (renameat(dfd
, tmp
, dfd
, itr
->name
) != 0) {
2285 CRIT("renameat(%s, %s, %s, %s): %m\n",
2286 dname
, tmp
, dname
, itr
->name
);
2292 ERR("Could not create index '%s'. Output is truncated: %s\n",
2293 itr
->name
, strerror(-err
));
2304 static void depmod_add_fake_syms(struct depmod
*depmod
)
2306 /* __this_module is magic inserted by kernel loader. */
2307 depmod_symbol_add(depmod
, "__this_module", 0, NULL
);
2308 /* On S390, this is faked up too */
2309 depmod_symbol_add(depmod
, "_GLOBAL_OFFSET_TABLE_", 0, NULL
);
2312 static int depmod_load_symvers(struct depmod
*depmod
, const char *filename
)
2316 unsigned int linenum
= 0;
2318 fp
= fopen(filename
, "r");
2321 DBG("load symvers: %s: %m\n", filename
);
2324 DBG("load symvers: %s\n", filename
);
2326 /* eg. "0xb352177e\tfind_first_bit\tvmlinux\tEXPORT_SYMBOL" */
2327 while (fgets(line
, sizeof(line
), fp
) != NULL
) {
2328 const char *ver
, *sym
, *where
;
2334 ver
= strtok(line
, " \t");
2335 sym
= strtok(NULL
, " \t");
2336 where
= strtok(NULL
, " \t");
2337 if (!ver
|| !sym
|| !where
)
2340 if (!streq(where
, "vmlinux"))
2343 crc
= strtoull(ver
, &verend
, 16);
2344 if (verend
[0] != '\0') {
2345 ERR("%s:%u Invalid symbol version %s: %m\n",
2346 filename
, linenum
, ver
);
2350 depmod_symbol_add(depmod
, sym
, crc
, NULL
);
2352 depmod_add_fake_syms(depmod
);
2354 DBG("loaded symvers: %s\n", filename
);
2360 static int depmod_load_system_map(struct depmod
*depmod
, const char *filename
)
2362 const char ksymstr
[] = "__ksymtab_";
2363 const size_t ksymstr_len
= sizeof(ksymstr
) - 1;
2366 unsigned int linenum
= 0;
2368 fp
= fopen(filename
, "r");
2371 DBG("load System.map: %s: %m\n", filename
);
2374 DBG("load System.map: %s\n", filename
);
2376 /* eg. c0294200 R __ksymtab_devfs_alloc_devnum */
2377 while (fgets(line
, sizeof(line
), fp
) != NULL
) {
2382 p
= strchr(line
, ' ');
2384 goto invalid_syntax
;
2388 goto invalid_syntax
;
2391 /* Covers gpl-only and normal symbols. */
2392 if (strncmp(p
, ksymstr
, ksymstr_len
) != 0)
2395 end
= strchr(p
, '\n');
2399 depmod_symbol_add(depmod
, p
+ ksymstr_len
, 0, NULL
);
2403 ERR("%s:%u: invalid line: %s\n", filename
, linenum
, line
);
2405 depmod_add_fake_syms(depmod
);
2407 DBG("loaded System.map: %s\n", filename
);
2414 static int depfile_up_to_date_dir(DIR *d
, time_t mtime
, size_t baselen
, char *path
)
2417 int err
= 1, dfd
= dirfd(d
);
2419 while ((de
= readdir(d
)) != NULL
) {
2420 const char *name
= de
->d_name
;
2424 if (name
[0] == '.' && (name
[1] == '\0' ||
2425 (name
[1] == '.' && name
[2] == '\0')))
2427 if (streq(name
, "build") || streq(name
, "source"))
2429 namelen
= strlen(name
);
2430 if (baselen
+ namelen
+ 2 >= PATH_MAX
) {
2431 path
[baselen
] = '\0';
2432 ERR("path is too long %s%s %zd\n", path
, name
);
2436 if (fstatat(dfd
, name
, &st
, 0) < 0) {
2437 ERR("fstatat(%d, %s): %m\n", dfd
, name
);
2441 if (S_ISDIR(st
.st_mode
)) {
2444 memcpy(path
+ baselen
, name
, namelen
+ 1);
2445 if (baselen
+ namelen
+ 2 + NAME_MAX
>= PATH_MAX
) {
2446 ERR("directory path is too long %s\n", path
);
2449 fd
= openat(dfd
, name
, O_RDONLY
);
2451 ERR("openat(%d, %s, O_RDONLY): %m\n",
2455 subdir
= fdopendir(fd
);
2456 if (subdir
== NULL
) {
2457 ERR("fdopendir(%d): %m\n", fd
);
2461 path
[baselen
+ namelen
] = '/';
2462 path
[baselen
+ namelen
+ 1] = '\0';
2463 err
= depfile_up_to_date_dir(subdir
, mtime
,
2464 baselen
+ namelen
+ 1,
2467 } else if (S_ISREG(st
.st_mode
)) {
2468 const struct kmod_ext
*eitr
;
2469 uint8_t matches
= 0;
2470 for (eitr
= kmod_exts
; eitr
->ext
!= NULL
; eitr
++) {
2471 if (namelen
<= eitr
->len
)
2473 if (streq(name
+ namelen
- eitr
->len
, eitr
->ext
)) {
2480 memcpy(path
+ baselen
, name
, namelen
+ 1);
2481 err
= st
.st_mtime
<= mtime
;
2483 DBG("%s %"PRIu64
" is newer than %"PRIu64
"\n",
2484 path
, (uint64_t)st
.st_mtime
,
2488 ERR("unsupported file type %s: %o\n",
2489 path
, st
.st_mode
& S_IFMT
);
2494 break; /* outdated! */
2496 path
[baselen
+ namelen
] = '\0';
2497 ERR("failed %s: %s\n", path
, strerror(-err
));
2498 err
= 1; /* ignore errors */
2505 /* uptodate: 1, outdated: 0, errors < 0 */
2506 static int depfile_up_to_date(const char *dirname
)
2508 char path
[PATH_MAX
];
2509 DIR *d
= opendir(dirname
);
2515 ERR("could not open directory %s: %m\n", dirname
);
2519 if (fstatat(dirfd(d
), "modules.dep", &st
, 0) != 0) {
2521 ERR("could not fstatat(%s, modules.dep): %m\n", dirname
);
2526 baselen
= strlen(dirname
);
2527 memcpy(path
, dirname
, baselen
);
2528 path
[baselen
] = '/';
2530 path
[baselen
] = '\0';
2532 err
= depfile_up_to_date_dir(d
, st
.st_mtime
, baselen
, path
);
2537 static int is_version_number(const char *version
)
2539 unsigned int d1
, d2
;
2540 return (sscanf(version
, "%u.%u", &d1
, &d2
) == 2);
2543 static int do_depmod(int argc
, char *argv
[])
2546 int err
= 0, all
= 0, maybe_all
= 0, n_config_paths
= 0;
2548 const char **config_paths
= NULL
;
2549 const char *system_map
= NULL
;
2550 const char *module_symvers
= NULL
;
2551 const char *null_kmod_config
= NULL
;
2553 struct kmod_ctx
*ctx
= NULL
;
2555 struct depmod depmod
;
2557 memset(&cfg
, 0, sizeof(cfg
));
2558 memset(&depmod
, 0, sizeof(depmod
));
2562 c
= getopt_long(argc
, argv
, cmdopts_s
, cmdopts
, &idx
);
2573 root
= path_make_absolute_cwd(optarg
);
2576 size_t bytes
= sizeof(char *) * (n_config_paths
+ 2);
2577 void *tmp
= realloc(config_paths
, bytes
);
2579 fputs("Error: out-of-memory\n", stderr
);
2580 goto cmdline_failed
;
2583 config_paths
[n_config_paths
] = optarg
;
2585 config_paths
[n_config_paths
] = NULL
;
2589 module_symvers
= optarg
;
2590 cfg
.check_symvers
= 1;
2593 system_map
= optarg
;
2596 cfg
.print_unknown
= 1;
2605 if (optarg
[1] != '\0') {
2606 CRIT("-P only takes a single char\n");
2607 goto cmdline_failed
;
2609 cfg
.sym_prefix
= optarg
[0];
2619 WRN("Ignored deprecated option --%s\n",
2622 WRN("Ignored deprecated option -%c\n", c
);
2628 return EXIT_SUCCESS
;
2630 puts(PACKAGE
" version " VERSION
);
2632 return EXIT_SUCCESS
;
2634 goto cmdline_failed
;
2636 ERR("unexpected getopt_long() value '%c'.\n", c
);
2637 goto cmdline_failed
;
2641 if (optind
< argc
&& is_version_number(argv
[optind
])) {
2642 cfg
.kversion
= argv
[optind
];
2645 if (uname(&un
) < 0) {
2646 CRIT("uname() failed: %s\n", strerror(errno
));
2647 goto cmdline_failed
;
2649 cfg
.kversion
= un
.release
;
2652 cfg
.dirnamelen
= snprintf(cfg
.dirname
, PATH_MAX
,
2653 "%s/lib/modules/%s",
2654 root
== NULL
? "" : root
, cfg
.kversion
);
2662 /* ignore up-to-date errors (< 0) */
2663 if (depfile_up_to_date(cfg
.dirname
) == 1) {
2664 DBG("%s/modules.dep is up to date!\n", cfg
.dirname
);
2667 DBG("%s/modules.dep is outdated, do -a\n", cfg
.dirname
);
2671 ctx
= kmod_new(cfg
.dirname
, &null_kmod_config
);
2673 CRIT("kmod_new(\"%s\", {NULL}) failed: %m\n", cfg
.dirname
);
2674 goto cmdline_failed
;
2676 kmod_set_log_priority(ctx
, verbose
);
2678 err
= depmod_init(&depmod
, &cfg
, ctx
);
2680 CRIT("depmod_init: %s\n", strerror(-err
));
2681 goto depmod_init_failed
;
2683 ctx
= NULL
; /* owned by depmod */
2685 if (module_symvers
!= NULL
) {
2686 err
= depmod_load_symvers(&depmod
, module_symvers
);
2688 CRIT("could not load %s: %s\n", module_symvers
,
2690 goto cmdline_failed
;
2692 } else if (system_map
!= NULL
) {
2693 err
= depmod_load_system_map(&depmod
, system_map
);
2695 CRIT("could not load %s: %s\n", system_map
,
2697 goto cmdline_failed
;
2699 } else if (cfg
.print_unknown
) {
2700 WRN("-e needs -E or -F\n");
2701 cfg
.print_unknown
= 0;
2705 err
= cfg_load(&cfg
, config_paths
);
2707 CRIT("could not load configuration files\n");
2708 goto cmdline_modules_failed
;
2710 err
= depmod_modules_search(&depmod
);
2712 CRIT("could not search modules: %s\n", strerror(-err
));
2713 goto cmdline_modules_failed
;
2718 for (i
= optind
; i
< argc
; i
++) {
2719 const char *path
= argv
[i
];
2720 struct kmod_module
*mod
;
2722 if (path
[0] != '/') {
2723 CRIT("%s: not absolute path.\n", path
);
2724 goto cmdline_modules_failed
;
2727 err
= kmod_module_new_from_path(depmod
.ctx
, path
, &mod
);
2729 CRIT("could not create module %s: %s\n",
2730 path
, strerror(-err
));
2731 goto cmdline_modules_failed
;
2734 err
= depmod_module_add(&depmod
, mod
);
2736 CRIT("could not add module %s: %s\n",
2737 path
, strerror(-err
));
2738 kmod_module_unref(mod
);
2739 goto cmdline_modules_failed
;
2744 err
= depmod_modules_build_array(&depmod
);
2746 CRIT("could not build module array: %s\n",
2748 goto cmdline_modules_failed
;
2751 depmod_modules_sort(&depmod
);
2752 err
= depmod_load(&depmod
);
2754 goto cmdline_modules_failed
;
2756 err
= depmod_output(&depmod
, out
);
2759 depmod_shutdown(&depmod
);
2762 return err
>= 0 ? EXIT_SUCCESS
: EXIT_FAILURE
;
2764 cmdline_modules_failed
:
2765 depmod_shutdown(&depmod
);
2773 return EXIT_FAILURE
;
2776 const struct kmod_cmd kmod_cmd_compat_depmod
= {
2779 .help
= "compat depmod command",