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 static const char CFG_BUILTIN_KEY
[] = "built-in";
44 static const char *default_cfg_paths
[] = {
46 SYSCONFDIR
"/depmod.d",
51 static const char cmdopts_s
[] = "aAb:C:E:F:euqrvnP:wmVh";
52 static const struct option cmdopts
[] = {
53 { "all", no_argument
, 0, 'a' },
54 { "quick", no_argument
, 0, 'A' },
55 { "basedir", required_argument
, 0, 'b' },
56 { "config", required_argument
, 0, 'C' },
57 { "symvers", required_argument
, 0, 'E' },
58 { "filesyms", required_argument
, 0, 'F' },
59 { "errsyms", no_argument
, 0, 'e' },
60 { "unresolved-error", no_argument
, 0, 'u' }, /* deprecated */
61 { "quiet", no_argument
, 0, 'q' }, /* deprecated */
62 { "root", no_argument
, 0, 'r' }, /* deprecated */
63 { "verbose", no_argument
, 0, 'v' },
64 { "show", no_argument
, 0, 'n' },
65 { "dry-run", no_argument
, 0, 'n' },
66 { "symbol-prefix", no_argument
, 0, 'P' },
67 { "warn", no_argument
, 0, 'w' },
68 { "map", no_argument
, 0, 'm' }, /* deprecated */
69 { "version", no_argument
, 0, 'V' },
70 { "help", no_argument
, 0, 'h' },
74 static void help(void)
77 "\t%s -[aA] [options] [forced_version]\n"
79 "If no arguments (except options) are given, \"depmod -a\" is assumed\n"
81 "depmod will output a dependency list suitable for the modprobe utility.\n"
84 "\t-a, --all Probe all modules\n"
85 "\t-A, --quick Only does the work if there's a new module\n"
86 "\t-e, --errsyms Report not supplied symbols\n"
87 "\t-n, --show Write the dependency file on stdout only\n"
88 "\t-P, --symbol-prefix Architecture symbol prefix\n"
89 "\t-C, --config=PATH Read configuration from PATH\n"
90 "\t-v, --verbose Enable verbose mode\n"
91 "\t-w, --warn Warn on duplicates\n"
92 "\t-V, --version show version\n"
93 "\t-h, --help show this help\n"
95 "The following options are useful for people managing distributions:\n"
96 "\t-b, --basedir=DIR Use an image of a module tree.\n"
97 "\t-F, --filesyms=FILE Use the file instead of the\n"
98 "\t current kernel symbols.\n"
99 "\t-E, --symvers=FILE Use Module.symvers file to check\n"
100 "\t symbol versions.\n",
101 program_invocation_short_name
);
104 static inline void _show(const char *fmt
, ...)
108 if (verbose
<= DEFAULT_VERBOSE
)
112 vfprintf(stdout
, fmt
, args
);
116 #define SHOW(...) _show(__VA_ARGS__)
119 /* binary index write *************************************************/
120 #include <arpa/inet.h>
122 /* BEGIN: code from module-init-tools/index.c just modified to compile here.
124 * Original copyright:
125 * index.c: module index file shared functions for modprobe and depmod
126 * Copyright (C) 2008 Alan Jenkins <alan-jenkins@tuffmail.co.uk>.
128 * These programs are free software; you can redistribute it and/or modify
129 * it under the terms of the GNU General Public License as published by
130 * the Free Software Foundation; either version 2 of the License, or
131 * (at your option) any later version.
133 * This program is distributed in the hope that it will be useful,
134 * but WITHOUT ANY WARRANTY; without even the implied warranty of
135 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
136 * GNU General Public License for more details.
138 * You should have received a copy of the GNU General Public License
139 * along with these programs. If not, see <http://www.gnu.org/licenses/>.
142 /* Integers are stored as 32 bit unsigned in "network" order, i.e. MSB first.
143 All files start with a magic number.
145 Magic spells "BOOTFAST". Second one used on newer versioned binary files.
147 /* #define INDEX_MAGIC_OLD 0xB007FA57 */
148 #define INDEX_MAGIC 0xB007F457
150 /* We use a version string to keep track of changes to the binary format
151 * This is stored in the form: INDEX_MAJOR (hi) INDEX_MINOR (lo) just in
152 * case we ever decide to have minor changes that are not incompatible.
155 #define INDEX_VERSION_MAJOR 0x0002
156 #define INDEX_VERSION_MINOR 0x0001
157 #define INDEX_VERSION ((INDEX_VERSION_MAJOR<<16)|INDEX_VERSION_MINOR)
159 /* The index file maps keys to values. Both keys and values are ASCII strings.
160 Each key can have multiple values. Values are sorted by an integer priority.
162 The reader also implements a wildcard search (including range expressions)
163 where the keys in the index are treated as patterns.
164 This feature is required for module aliases.
167 /* Implementation is based on a radix tree, or "trie".
168 Each arc from parent to child is labelled with a character.
169 Each path from the root represents a string.
171 == Example strings ==
181 * Marked node, representing a key and it's values.
192 Naive implementations tend to be very space inefficient; child pointers
193 are stored in arrays indexed by character, but most child pointers are null.
195 Our implementation uses a scheme described by Wikipedia as a Patrica trie,
197 "easiest to understand as a space-optimized trie where
198 each node with only one child is merged with its child"
209 We still use arrays of child pointers indexed by a single character;
210 the remaining characters of the label are stored as a "prefix" in the child.
212 The paper describing the original Patrica trie works on individiual bits -
213 each node has a maximum of two children, which increases space efficiency.
214 However for this application it is simpler to use the ASCII character set.
215 Since the index file is read-only, it can be compressed by omitting null
216 child pointers at the start and end of arrays.
219 #define INDEX_PRIORITY_MIN UINT32_MAX
222 struct index_value
*next
;
223 unsigned int priority
;
227 /* In-memory index (depmod only) */
229 #define INDEX_CHILDMAX 128
231 char *prefix
; /* path compression */
232 struct index_value
*values
;
233 unsigned char first
; /* range of child nodes */
235 struct index_node
*children
[INDEX_CHILDMAX
]; /* indexed by character */
240 uint32_t magic = INDEX_MAGIC;
241 uint32_t version = INDEX_VERSION;
242 uint32_t root_offset;
244 (node_offset & INDEX_NODE_MASK) specifies the file offset of nodes:
246 char[] prefix; // nul terminated
250 uint32_t children[last - first + 1];
252 uint32_t value_count;
255 char[] value; // nul terminated
256 } values[value_count];
258 (node_offset & INDEX_NODE_FLAGS) indicates which fields are present.
259 Empty prefixes are omitted, leaf nodes omit the three child-related fields.
261 This could be optimised further by adding a sparse child format
262 (indicated using a new flag).
265 /* Format of node offsets within index file */
267 INDEX_NODE_FLAGS
= 0xF0000000, /* Flags in high nibble */
268 INDEX_NODE_PREFIX
= 0x80000000,
269 INDEX_NODE_VALUES
= 0x40000000,
270 INDEX_NODE_CHILDS
= 0x20000000,
272 INDEX_NODE_MASK
= 0x0FFFFFFF, /* Offset value */
275 static struct index_node
*index_create(void)
277 struct index_node
*node
;
279 node
= NOFAIL(calloc(sizeof(struct index_node
), 1));
280 node
->prefix
= NOFAIL(strdup(""));
281 node
->first
= INDEX_CHILDMAX
;
286 static void index_values_free(struct index_value
*values
)
289 struct index_value
*value
= values
;
291 values
= value
->next
;
296 static void index_destroy(struct index_node
*node
)
300 for (c
= node
->first
; c
<= node
->last
; c
++) {
301 struct index_node
*child
= node
->children
[c
];
304 index_destroy(child
);
306 index_values_free(node
->values
);
311 static void index__checkstring(const char *str
)
315 for (i
= 0; str
[i
]; i
++) {
318 if (ch
>= INDEX_CHILDMAX
)
319 CRIT("Module index: bad character '%c'=0x%x - only 7-bit ASCII is supported:"
320 "\n%s\n", (char) ch
, (int) ch
, str
);
324 static int index_add_value(struct index_value
**values
,
325 const char *value
, unsigned int priority
)
327 struct index_value
*v
;
331 /* report the presence of duplicate values */
332 for (v
= *values
; v
; v
= v
->next
) {
333 if (streq(v
->value
, value
))
337 /* find position to insert value */
338 while (*values
&& (*values
)->priority
< priority
)
339 values
= &(*values
)->next
;
342 v
= NOFAIL(calloc(sizeof(struct index_value
) + len
+ 1, 1));
344 v
->priority
= priority
;
345 memcpy(v
->value
, value
, len
+ 1);
351 static int index_insert(struct index_node
*node
, const char *key
,
352 const char *value
, unsigned int priority
)
354 int i
= 0; /* index within str */
357 index__checkstring(key
);
358 index__checkstring(value
);
361 int j
; /* index within node->prefix */
363 /* Ensure node->prefix is a prefix of &str[i].
364 If it is not already, then we must split node. */
365 for (j
= 0; node
->prefix
[j
]; j
++) {
366 ch
= node
->prefix
[j
];
368 if (ch
!= key
[i
+j
]) {
369 char *prefix
= node
->prefix
;
370 struct index_node
*n
;
372 /* New child is copy of node with prefix[j+1..N] */
373 n
= NOFAIL(calloc(sizeof(struct index_node
), 1));
374 memcpy(n
, node
, sizeof(struct index_node
));
375 n
->prefix
= NOFAIL(strdup(&prefix
[j
+1]));
377 /* Parent has prefix[0..j], child at prefix[j] */
378 memset(node
, 0, sizeof(struct index_node
));
380 node
->prefix
= prefix
;
383 node
->children
[ch
] = n
;
388 /* j is now length of node->prefix */
393 return index_add_value(&node
->values
, value
, priority
);
395 if (!node
->children
[ch
]) {
396 struct index_node
*child
;
398 if (ch
< node
->first
)
402 node
->children
[ch
] = NOFAIL(calloc(sizeof(struct index_node
), 1));
404 child
= node
->children
[ch
];
405 child
->prefix
= NOFAIL(strdup(&key
[i
+1]));
406 child
->first
= INDEX_CHILDMAX
;
407 index_add_value(&child
->values
, value
, priority
);
412 /* Descend into child node and continue */
413 node
= node
->children
[ch
];
418 static int index__haschildren(const struct index_node
*node
)
420 return node
->first
< INDEX_CHILDMAX
;
423 /* Recursive post-order traversal
425 Pre-order would make for better read-side buffering / readahead / caching.
426 (post-order means you go backwards in the file as you descend the tree).
427 However, index reading is already fast enough.
428 Pre-order is simpler for writing, and depmod is already slow.
430 static uint32_t index_write__node(const struct index_node
*node
, FILE *out
)
432 uint32_t *child_offs
= NULL
;
439 /* Write children and save their offsets */
440 if (index__haschildren(node
)) {
441 const struct index_node
*child
;
444 child_count
= node
->last
- node
->first
+ 1;
445 child_offs
= NOFAIL(malloc(child_count
* sizeof(uint32_t)));
447 for (i
= 0; i
< child_count
; i
++) {
448 child
= node
->children
[node
->first
+ i
];
449 child_offs
[i
] = htonl(index_write__node(child
, out
));
453 /* Now write this node */
456 if (node
->prefix
[0]) {
457 fputs(node
->prefix
, out
);
459 offset
|= INDEX_NODE_PREFIX
;
463 fputc(node
->first
, out
);
464 fputc(node
->last
, out
);
465 fwrite(child_offs
, sizeof(uint32_t), child_count
, out
);
467 offset
|= INDEX_NODE_CHILDS
;
471 const struct index_value
*v
;
472 unsigned int value_count
;
476 for (v
= node
->values
; v
!= NULL
; v
= v
->next
)
478 u
= htonl(value_count
);
479 fwrite(&u
, sizeof(u
), 1, out
);
481 for (v
= node
->values
; v
!= NULL
; v
= v
->next
) {
482 u
= htonl(v
->priority
);
483 fwrite(&u
, sizeof(u
), 1, out
);
484 fputs(v
->value
, out
);
487 offset
|= INDEX_NODE_VALUES
;
493 static void index_write(const struct index_node
*node
, FILE *out
)
495 long initial_offset
, final_offset
;
498 u
= htonl(INDEX_MAGIC
);
499 fwrite(&u
, sizeof(u
), 1, out
);
500 u
= htonl(INDEX_VERSION
);
501 fwrite(&u
, sizeof(u
), 1, out
);
503 /* Second word is reserved for the offset of the root node */
504 initial_offset
= ftell(out
);
506 fwrite(&u
, sizeof(uint32_t), 1, out
);
509 u
= htonl(index_write__node(node
, out
));
511 /* Update first word */
512 final_offset
= ftell(out
);
513 fseek(out
, initial_offset
, SEEK_SET
);
514 fwrite(&u
, sizeof(uint32_t), 1, out
);
515 fseek(out
, final_offset
, SEEK_SET
);
518 /* END: code from module-init-tools/index.c just modified to compile here.
521 /* utils (variants of libkmod-utils.c) *********************************/
522 static const char *underscores2(const char *input
, char *output
, size_t outputlen
)
526 for (i
= 0; input
[i
] != '\0' && i
< outputlen
- 1; i
++) {
533 WRN("Unmatched bracket in %s\n", input
);
537 size_t off
= strcspn(input
+ i
, "]");
538 if (input
[i
+ off
] == '\0') {
539 WRN("Unmatched bracket in %s\n", input
);
542 memcpy(output
+ i
, input
+ i
, off
+ 1);
548 output
[i
] = input
[i
];
556 /* configuration parsing **********************************************/
557 struct cfg_override
{
558 struct cfg_override
*next
;
564 struct cfg_search
*next
;
571 const char *kversion
;
572 char dirname
[PATH_MAX
];
575 uint8_t check_symvers
;
576 uint8_t print_unknown
;
578 struct cfg_override
*overrides
;
579 struct cfg_search
*searches
;
582 static int cfg_search_add(struct cfg
*cfg
, const char *path
, uint8_t builtin
)
584 struct cfg_search
*s
;
590 len
= strlen(path
) + 1;
592 s
= malloc(sizeof(struct cfg_search
) + len
);
594 ERR("search add: out of memory\n");
597 s
->builtin
= builtin
;
602 memcpy(s
->path
, path
, len
);
605 DBG("search add: %s, builtin=%hhu\n", path
, builtin
);
607 s
->next
= cfg
->searches
;
612 static void cfg_search_free(struct cfg_search
*s
)
617 static int cfg_override_add(struct cfg
*cfg
, const char *modname
, const char *subdir
)
619 struct cfg_override
*o
;
620 size_t modnamelen
= strlen(modname
);
621 size_t subdirlen
= strlen(subdir
);
624 o
= malloc(sizeof(struct cfg_override
) + subdirlen
+ 1
627 ERR("override add: out of memory\n");
630 memcpy(o
->path
, subdir
, subdirlen
);
635 memcpy(o
->path
+ i
, modname
, modnamelen
);
637 o
->path
[i
] = '\0'; /* no extension, so we can match .ko/.ko.gz */
641 DBG("override add: %s\n", o
->path
);
643 o
->next
= cfg
->overrides
;
648 static void cfg_override_free(struct cfg_override
*o
)
653 static int cfg_kernel_matches(const struct cfg
*cfg
, const char *pattern
)
659 if (streq(pattern
, "*"))
662 if (regcomp(&re
, pattern
, REG_EXTENDED
|REG_NOSUB
) != 0)
665 status
= regexec(&re
, cfg
->kversion
, 0, NULL
, 0);
671 static int cfg_file_parse(struct cfg
*cfg
, const char *filename
)
675 unsigned int linenum
= 0;
678 fp
= fopen(filename
, "r");
681 ERR("file parse %s: %m\n", filename
);
685 while ((line
= getline_wrapped(fp
, &linenum
)) != NULL
) {
688 if (line
[0] == '\0' || line
[0] == '#')
691 cmd
= strtok_r(line
, "\t ", &saveptr
);
695 if (streq(cmd
, "search")) {
697 while ((sp
= strtok_r(NULL
, "\t ", &saveptr
)) != NULL
) {
698 uint8_t builtin
= streq(sp
, CFG_BUILTIN_KEY
);
699 cfg_search_add(cfg
, sp
, builtin
);
701 } else if (streq(cmd
, "override")) {
702 const char *modname
= strtok_r(NULL
, "\t ", &saveptr
);
703 const char *version
= strtok_r(NULL
, "\t ", &saveptr
);
704 const char *subdir
= strtok_r(NULL
, "\t ", &saveptr
);
706 if (modname
== NULL
|| version
== NULL
||
710 if (!cfg_kernel_matches(cfg
, version
)) {
711 INF("%s:%u: override kernel did not match %s\n",
712 filename
, linenum
, version
);
716 cfg_override_add(cfg
, modname
, subdir
);
717 } else if (streq(cmd
, "include")
718 || streq(cmd
, "make_map_files")) {
719 INF("%s:%u: command %s not implemented yet\n",
720 filename
, linenum
, cmd
);
723 ERR("%s:%u: ignoring bad line starting with '%s'\n",
724 filename
, linenum
, cmd
);
736 static int cfg_files_filter_out(DIR *d
, const char *dir
, const char *name
)
738 size_t len
= strlen(name
);
744 if (len
< 6 || !streq(name
+ len
- 5, ".conf")) {
745 INF("All cfg files need .conf: %s/%s\n", dir
, name
);
749 fstatat(dirfd(d
), name
, &st
, 0);
750 if (S_ISDIR(st
.st_mode
)) {
751 ERR("Directories inside directories are not supported: %s/%s\n",
766 static void cfg_file_free(struct cfg_file
*f
)
771 static int cfg_files_insert_sorted(struct cfg_file
***p_files
, size_t *p_n_files
,
772 const char *dir
, const char *name
)
774 struct cfg_file
**files
, *f
;
775 size_t i
, n_files
, namelen
, dirlen
;
778 dirlen
= strlen(dir
);
780 namelen
= strlen(name
);
782 name
= basename(dir
);
783 namelen
= strlen(name
);
784 dirlen
-= namelen
+ 1;
787 n_files
= *p_n_files
;
789 for (i
= 0; i
< n_files
; i
++) {
790 int cmp
= strcmp(name
, files
[i
]->name
);
792 DBG("Ignoring duplicate config file: %.*s/%s\n",
793 (int)dirlen
, dir
, name
);
799 f
= malloc(sizeof(struct cfg_file
) + dirlen
+ namelen
+ 2);
801 ERR("files insert sorted: out of memory\n");
805 tmp
= realloc(files
, sizeof(struct cfg_file
*) * (n_files
+ 1));
807 ERR("files insert sorted: out of memory\n");
811 *p_files
= files
= tmp
;
814 memmove(files
+ i
+ 1, files
+ i
,
815 sizeof(struct cfg_file
*) * (n_files
- i
));
820 f
->namelen
= namelen
;
821 f
->name
= f
->path
+ dirlen
+ 1;
822 memcpy(f
->path
, dir
, dirlen
);
823 f
->path
[dirlen
] = '/';
824 memcpy(f
->path
+ dirlen
+ 1, name
, namelen
);
825 f
->path
[dirlen
+ 1 + namelen
] = '\0';
827 *p_n_files
= n_files
+ 1;
832 * Insert configuration files ignoring duplicates
834 static int cfg_files_list(struct cfg_file
***p_files
, size_t *p_n_files
,
841 if (stat(path
, &st
) != 0) {
843 DBG("could not stat '%s': %m\n", path
);
847 if (S_ISREG(st
.st_mode
)) {
848 cfg_files_insert_sorted(p_files
, p_n_files
, path
, NULL
);
850 } if (!S_ISDIR(st
.st_mode
)) {
851 ERR("unsupported file mode %s: %#x\n", path
, st
.st_mode
);
857 ERR("files list %s: %m\n", path
);
862 struct dirent ent
, *entp
;
864 err
= readdir_r(d
, &ent
, &entp
);
866 ERR("reading entry %s\n", strerror(-err
));
871 if (cfg_files_filter_out(d
, path
, entp
->d_name
))
874 cfg_files_insert_sorted(p_files
, p_n_files
, path
, entp
->d_name
);
878 DBG("parsed configuration files from %s\n", path
);
882 static int cfg_load(struct cfg
*cfg
, const char * const *cfg_paths
)
884 size_t i
, n_files
= 0;
885 struct cfg_file
**files
= NULL
;
887 if (cfg_paths
== NULL
)
888 cfg_paths
= default_cfg_paths
;
890 for (i
= 0; cfg_paths
[i
] != NULL
; i
++)
891 cfg_files_list(&files
, &n_files
, cfg_paths
[i
]);
893 for (i
= 0; i
< n_files
; i
++) {
894 struct cfg_file
*f
= files
[i
];
895 cfg_file_parse(cfg
, f
->path
);
900 /* For backward compatibility add "updates" to the head of the search
901 * list here. But only if there was no "search" option specified.
903 if (cfg
->searches
== NULL
)
904 cfg_search_add(cfg
, "updates", 0);
909 static void cfg_free(struct cfg
*cfg
)
911 while (cfg
->overrides
) {
912 struct cfg_override
*tmp
= cfg
->overrides
;
913 cfg
->overrides
= cfg
->overrides
->next
;
914 cfg_override_free(tmp
);
917 while (cfg
->searches
) {
918 struct cfg_search
*tmp
= cfg
->searches
;
919 cfg
->searches
= cfg
->searches
->next
;
920 cfg_search_free(tmp
);
925 /* depmod calculations ***********************************************/
927 struct kmod_module
*kmod
;
929 const char *relpath
; /* path relative to '$ROOT/lib/modules/$VER/' */
930 char *uncrelpath
; /* same as relpath but ending in .ko */
931 struct kmod_list
*info_list
;
932 struct kmod_list
*dep_sym_list
;
933 struct array deps
; /* struct symbol */
934 size_t baselen
; /* points to start of basename/filename */
936 int sort_idx
; /* sort index using modules.order */
937 int dep_sort_idx
; /* topological sort index */
938 uint16_t idx
; /* index in depmod->modules.array */
939 uint16_t users
; /* how many modules depend on this one */
940 uint8_t dep_loop
: 1;
951 const struct cfg
*cfg
;
952 struct kmod_ctx
*ctx
;
953 struct array modules
;
954 struct hash
*modules_by_uncrelpath
;
955 struct hash
*modules_by_name
;
956 struct hash
*symbols
;
957 unsigned int dep_loops
;
960 static void mod_free(struct mod
*mod
)
962 DBG("free %p kmod=%p, path=%s\n", mod
, mod
->kmod
, mod
->path
);
963 array_free_array(&mod
->deps
);
964 kmod_module_unref(mod
->kmod
);
965 kmod_module_info_free_list(mod
->info_list
);
966 kmod_module_dependency_symbols_free_list(mod
->dep_sym_list
);
967 free(mod
->uncrelpath
);
972 static int mod_add_dependency(struct mod
*mod
, struct symbol
*sym
)
976 DBG("%s depends on %s %s\n", mod
->path
, sym
->name
,
977 sym
->owner
!= NULL
? sym
->owner
->path
: "(unknown)");
979 if (sym
->owner
== NULL
)
982 err
= array_append_unique(&mod
->deps
, sym
->owner
);
989 SHOW("%s needs \"%s\": %s\n", mod
->path
, sym
->name
, sym
->owner
->path
);
993 static void symbol_free(struct symbol
*sym
)
995 DBG("free %p sym=%s, owner=%p %s\n", sym
, sym
->name
, sym
->owner
,
996 sym
->owner
!= NULL
? sym
->owner
->path
: "");
1000 static int depmod_init(struct depmod
*depmod
, struct cfg
*cfg
,
1001 struct kmod_ctx
*ctx
)
1008 array_init(&depmod
->modules
, 128);
1010 depmod
->modules_by_uncrelpath
= hash_new(512, NULL
);
1011 if (depmod
->modules_by_uncrelpath
== NULL
) {
1013 goto modules_by_uncrelpath_failed
;
1016 depmod
->modules_by_name
= hash_new(512, NULL
);
1017 if (depmod
->modules_by_name
== NULL
) {
1019 goto modules_by_name_failed
;
1022 depmod
->symbols
= hash_new(2048, (void (*)(void *))symbol_free
);
1023 if (depmod
->symbols
== NULL
) {
1025 goto symbols_failed
;
1031 hash_free(depmod
->modules_by_name
);
1032 modules_by_name_failed
:
1033 hash_free(depmod
->modules_by_uncrelpath
);
1034 modules_by_uncrelpath_failed
:
1038 static void depmod_shutdown(struct depmod
*depmod
)
1042 hash_free(depmod
->symbols
);
1044 hash_free(depmod
->modules_by_uncrelpath
);
1046 hash_free(depmod
->modules_by_name
);
1048 for (i
= 0; i
< depmod
->modules
.count
; i
++)
1049 mod_free(depmod
->modules
.array
[i
]);
1050 array_free_array(&depmod
->modules
);
1052 kmod_unref(depmod
->ctx
);
1055 static int depmod_module_add(struct depmod
*depmod
, struct kmod_module
*kmod
)
1057 const struct cfg
*cfg
= depmod
->cfg
;
1058 const char *modname
, *lastslash
;
1063 modname
= kmod_module_get_name(kmod
);
1064 modnamelen
= strlen(modname
) + 1;
1066 mod
= calloc(1, sizeof(struct mod
) + modnamelen
);
1070 mod
->sort_idx
= depmod
->modules
.count
+ 1;
1071 mod
->dep_sort_idx
= INT32_MAX
;
1072 memcpy(mod
->modname
, modname
, modnamelen
);
1073 mod
->modnamelen
= modnamelen
;
1075 array_init(&mod
->deps
, 4);
1077 mod
->path
= strdup(kmod_module_get_path(kmod
));
1078 lastslash
= strrchr(mod
->path
, '/');
1079 mod
->baselen
= lastslash
- mod
->path
;
1080 if (strncmp(mod
->path
, cfg
->dirname
, cfg
->dirnamelen
) == 0 &&
1081 mod
->path
[cfg
->dirnamelen
] == '/')
1082 mod
->relpath
= mod
->path
+ cfg
->dirnamelen
+ 1;
1084 mod
->relpath
= NULL
;
1086 err
= hash_add_unique(depmod
->modules_by_name
, mod
->modname
, mod
);
1088 ERR("hash_add_unique %s: %s\n", mod
->modname
, strerror(-err
));
1092 if (mod
->relpath
!= NULL
) {
1093 size_t uncrelpathlen
= lastslash
- mod
->relpath
+ modnamelen
1094 + kmod_exts
[KMOD_EXT_UNC
].len
;
1095 mod
->uncrelpath
= memdup(mod
->relpath
, uncrelpathlen
+ 1);
1096 mod
->uncrelpath
[uncrelpathlen
] = '\0';
1097 err
= hash_add_unique(depmod
->modules_by_uncrelpath
,
1098 mod
->uncrelpath
, mod
);
1100 ERR("hash_add_unique %s: %s\n",
1101 mod
->uncrelpath
, strerror(-err
));
1102 hash_del(depmod
->modules_by_name
, mod
->modname
);
1107 DBG("add %p kmod=%p, path=%s\n", mod
, kmod
, mod
->path
);
1112 free(mod
->uncrelpath
);
1117 static int depmod_module_del(struct depmod
*depmod
, struct mod
*mod
)
1119 DBG("del %p kmod=%p, path=%s\n", mod
, mod
->kmod
, mod
->path
);
1121 if (mod
->uncrelpath
!= NULL
)
1122 hash_del(depmod
->modules_by_uncrelpath
, mod
->uncrelpath
);
1124 hash_del(depmod
->modules_by_name
, mod
->modname
);
1130 /* returns if existing module @mod is higher priority than newpath.
1131 * note this is the inverse of module-init-tools is_higher_priority()
1133 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
)
1135 const struct cfg
*cfg
= depmod
->cfg
;
1136 const struct cfg_override
*ov
;
1137 const struct cfg_search
*se
;
1138 size_t newlen
= baselen
+ modnamelen
;
1139 size_t oldlen
= mod
->baselen
+ mod
->modnamelen
;
1140 const char *oldpath
= mod
->path
;
1141 int i
, bprio
= -1, oldprio
= -1, newprio
= -1;
1143 assert(strncmp(newpath
, cfg
->dirname
, cfg
->dirnamelen
) == 0);
1144 assert(strncmp(oldpath
, cfg
->dirname
, cfg
->dirnamelen
) == 0);
1146 newpath
+= cfg
->dirnamelen
+ 1;
1147 newlen
-= cfg
->dirnamelen
+ 1;
1148 oldpath
+= cfg
->dirnamelen
+ 1;
1149 oldlen
-= cfg
->dirnamelen
+ 1;
1151 DBG("comparing priorities of %s and %s\n",
1154 for (ov
= cfg
->overrides
; ov
!= NULL
; ov
= ov
->next
) {
1155 DBG("override %s\n", ov
->path
);
1156 if (newlen
== ov
->len
&& memcmp(ov
->path
, newpath
, newlen
) == 0)
1158 if (oldlen
== ov
->len
&& memcmp(ov
->path
, oldpath
, oldlen
) == 0)
1162 for (i
= 0, se
= cfg
->searches
; se
!= NULL
; se
= se
->next
, i
++) {
1163 DBG("search %s\n", se
->builtin
? "built-in" : se
->path
);
1166 else if (newlen
>= se
->len
&&
1167 memcmp(se
->path
, newpath
, se
->len
) == 0)
1169 else if (oldlen
>= se
->len
&&
1170 memcmp(se
->path
, oldpath
, se
->len
) == 0)
1179 DBG("priorities: built-in: %d, old: %d, new: %d\n",
1180 bprio
, newprio
, oldprio
);
1182 return newprio
<= oldprio
;
1185 static int depmod_modules_search_file(struct depmod
*depmod
, size_t baselen
, size_t namelen
, const char *path
)
1187 struct kmod_module
*kmod
;
1189 const char *relpath
;
1190 char modname
[PATH_MAX
];
1194 if (!path_ends_with_kmod_ext(path
, baselen
+ namelen
))
1197 if (path_to_modname(path
, modname
, &modnamelen
) == NULL
) {
1198 ERR("could not get modname from path %s\n", path
);
1202 relpath
= path
+ depmod
->cfg
->dirnamelen
+ 1;
1203 DBG("try %s (%s)\n", relpath
, modname
);
1205 mod
= hash_find(depmod
->modules_by_name
, modname
);
1209 if (depmod_module_is_higher_priority(depmod
, mod
, baselen
,
1210 namelen
, modnamelen
, path
)) {
1211 DBG("Ignored lower priority: %s, higher: %s\n",
1216 DBG("Replace lower priority %s with new module %s\n",
1217 mod
->relpath
, relpath
);
1218 err
= depmod_module_del(depmod
, mod
);
1220 ERR("could not del module %s: %s\n", mod
->path
, strerror(-err
));
1225 err
= kmod_module_new_from_path(depmod
->ctx
, path
, &kmod
);
1227 ERR("could not create module %s: %s\n", path
, strerror(-err
));
1231 err
= depmod_module_add(depmod
, kmod
);
1233 ERR("could not add module %s: %s\n",
1234 path
, strerror(-err
));
1235 kmod_module_unref(kmod
);
1241 static int depmod_modules_search_dir(struct depmod
*depmod
, DIR *d
, size_t baselen
, char *path
)
1244 int err
= 0, dfd
= dirfd(d
);
1246 while ((de
= readdir(d
)) != NULL
) {
1247 const char *name
= de
->d_name
;
1251 if (name
[0] == '.' && (name
[1] == '\0' ||
1252 (name
[1] == '.' && name
[2] == '\0')))
1254 if (streq(name
, "build") || streq(name
, "source"))
1256 namelen
= strlen(name
);
1257 if (baselen
+ namelen
+ 2 >= PATH_MAX
) {
1258 path
[baselen
] = '\0';
1259 ERR("path is too long %s%s %zd\n", path
, name
);
1262 memcpy(path
+ baselen
, name
, namelen
+ 1);
1264 if (de
->d_type
== DT_REG
)
1266 else if (de
->d_type
== DT_DIR
)
1270 if (fstatat(dfd
, name
, &st
, 0) < 0) {
1271 ERR("fstatat(%d, %s): %m\n", dfd
, name
);
1273 } else if (S_ISREG(st
.st_mode
))
1275 else if (S_ISDIR(st
.st_mode
))
1278 ERR("unsupported file type %s: %o\n",
1279 path
, st
.st_mode
& S_IFMT
);
1287 if (baselen
+ namelen
+ 2 + NAME_MAX
>= PATH_MAX
) {
1288 ERR("directory path is too long %s\n", path
);
1291 fd
= openat(dfd
, name
, O_RDONLY
);
1293 ERR("openat(%d, %s, O_RDONLY): %m\n",
1297 subdir
= fdopendir(fd
);
1298 if (subdir
== NULL
) {
1299 ERR("fdopendir(%d): %m\n", fd
);
1303 path
[baselen
+ namelen
] = '/';
1304 path
[baselen
+ namelen
+ 1] = '\0';
1305 err
= depmod_modules_search_dir(depmod
, subdir
,
1306 baselen
+ namelen
+ 1,
1310 err
= depmod_modules_search_file(depmod
, baselen
,
1315 path
[baselen
+ namelen
] = '\0';
1316 ERR("failed %s: %s\n", path
, strerror(-err
));
1317 err
= 0; /* ignore errors */
1324 static int depmod_modules_search(struct depmod
*depmod
)
1326 char path
[PATH_MAX
];
1327 DIR *d
= opendir(depmod
->cfg
->dirname
);
1332 ERR("could not open directory %s: %m\n", depmod
->cfg
->dirname
);
1336 baselen
= depmod
->cfg
->dirnamelen
;
1337 memcpy(path
, depmod
->cfg
->dirname
, baselen
);
1338 path
[baselen
] = '/';
1340 path
[baselen
] = '\0';
1342 err
= depmod_modules_search_dir(depmod
, d
, baselen
, path
);
1347 static int mod_cmp(const void *pa
, const void *pb
) {
1348 const struct mod
*a
= *(const struct mod
**)pa
;
1349 const struct mod
*b
= *(const struct mod
**)pb
;
1350 if (a
->dep_loop
== b
->dep_loop
)
1351 return a
->sort_idx
- b
->sort_idx
;
1352 else if (a
->dep_loop
)
1354 else if (b
->dep_loop
)
1356 return a
->sort_idx
- b
->sort_idx
;
1359 static int depmod_modules_build_array(struct depmod
*depmod
)
1361 struct hash_iter module_iter
;
1365 hash_iter_init(depmod
->modules_by_name
, &module_iter
);
1366 while (hash_iter_next(&module_iter
, NULL
, &v
)) {
1367 struct mod
*mod
= (struct mod
*) v
;
1368 mod
->idx
= depmod
->modules
.count
;
1369 err
= array_append(&depmod
->modules
, mod
);
1377 static void depmod_modules_sort(struct depmod
*depmod
)
1379 char order_file
[PATH_MAX
], line
[PATH_MAX
];
1381 unsigned idx
= 0, total
= 0;
1383 snprintf(order_file
, sizeof(order_file
), "%s/modules.order",
1384 depmod
->cfg
->dirname
);
1385 fp
= fopen(order_file
, "r");
1387 WRN("could not open %s: %m\n", order_file
);
1391 while (fgets(line
, sizeof(line
), fp
) != NULL
) {
1392 size_t len
= strlen(line
);
1396 if (line
[len
- 1] != '\n') {
1397 ERR("%s:%u corrupted line misses '\\n'\n",
1404 fseek(fp
, 0, SEEK_SET
);
1405 while (fgets(line
, sizeof(line
), fp
) != NULL
) {
1406 size_t len
= strlen(line
);
1412 line
[len
- 1] = '\0';
1414 mod
= hash_find(depmod
->modules_by_uncrelpath
, line
);
1417 mod
->sort_idx
= idx
- total
;
1420 array_sort(&depmod
->modules
, mod_cmp
);
1421 for (idx
= 0; idx
< depmod
->modules
.count
; idx
++) {
1422 struct mod
*m
= depmod
->modules
.array
[idx
];
1430 static int depmod_symbol_add(struct depmod
*depmod
, const char *name
,
1431 uint64_t crc
, const struct mod
*owner
)
1437 if (name
[0] == depmod
->cfg
->sym_prefix
)
1440 namelen
= strlen(name
) + 1;
1441 sym
= malloc(sizeof(struct symbol
) + namelen
);
1445 sym
->owner
= (struct mod
*)owner
;
1447 memcpy(sym
->name
, name
, namelen
);
1449 err
= hash_add(depmod
->symbols
, sym
->name
, sym
);
1455 DBG("add %p sym=%s, owner=%p %s\n", sym
, sym
->name
, owner
,
1456 owner
!= NULL
? owner
->path
: "");
1461 static struct symbol
*depmod_symbol_find(const struct depmod
*depmod
,
1464 if (name
[0] == '.') /* PPC64 needs this: .foo == foo */
1466 if (name
[0] == depmod
->cfg
->sym_prefix
)
1468 return hash_find(depmod
->symbols
, name
);
1471 static int depmod_load_modules(struct depmod
*depmod
)
1473 struct mod
**itr
, **itr_end
;
1475 DBG("load symbols (%zd modules)\n", depmod
->modules
.count
);
1477 itr
= (struct mod
**)depmod
->modules
.array
;
1478 itr_end
= itr
+ depmod
->modules
.count
;
1479 for (; itr
< itr_end
; itr
++) {
1480 struct mod
*mod
= *itr
;
1481 struct kmod_list
*l
, *list
= NULL
;
1482 int err
= kmod_module_get_symbols(mod
->kmod
, &list
);
1485 DBG("ignoring %s: no symbols\n", mod
->path
);
1487 ERR("failed to load symbols from %s: %s\n",
1488 mod
->path
, strerror(-err
));
1491 kmod_list_foreach(l
, list
) {
1492 const char *name
= kmod_module_symbol_get_symbol(l
);
1493 uint64_t crc
= kmod_module_symbol_get_crc(l
);
1494 depmod_symbol_add(depmod
, name
, crc
, mod
);
1496 kmod_module_symbols_free_list(list
);
1499 kmod_module_get_info(mod
->kmod
, &mod
->info_list
);
1500 kmod_module_get_dependency_symbols(mod
->kmod
,
1501 &mod
->dep_sym_list
);
1502 kmod_module_unref(mod
->kmod
);
1506 DBG("loaded symbols (%zd modules, %zd symbols)\n",
1507 depmod
->modules
.count
, hash_get_count(depmod
->symbols
));
1512 static int depmod_load_module_dependencies(struct depmod
*depmod
, struct mod
*mod
)
1514 const struct cfg
*cfg
= depmod
->cfg
;
1515 struct kmod_list
*l
;
1517 DBG("do dependencies of %s\n", mod
->path
);
1518 kmod_list_foreach(l
, mod
->dep_sym_list
) {
1519 const char *name
= kmod_module_dependency_symbol_get_symbol(l
);
1520 uint64_t crc
= kmod_module_dependency_symbol_get_crc(l
);
1521 int bindtype
= kmod_module_dependency_symbol_get_bind(l
);
1522 struct symbol
*sym
= depmod_symbol_find(depmod
, name
);
1523 uint8_t is_weak
= bindtype
== KMOD_SYMBOL_WEAK
;
1526 DBG("%s needs (%c) unknown symbol %s\n",
1527 mod
->path
, bindtype
, name
);
1528 if (cfg
->print_unknown
&& !is_weak
)
1529 WRN("%s needs unknown symbol %s\n",
1534 if (cfg
->check_symvers
&& sym
->crc
!= crc
&& !is_weak
) {
1535 DBG("symbol %s (%#"PRIx64
") module %s (%#"PRIx64
")\n",
1536 sym
->name
, sym
->crc
, mod
->path
, crc
);
1537 if (cfg
->print_unknown
)
1538 WRN("%s disagrees about version of symbol %s\n",
1542 mod_add_dependency(mod
, sym
);
1548 static int depmod_load_dependencies(struct depmod
*depmod
)
1550 struct mod
**itr
, **itr_end
;
1552 DBG("load dependencies (%zd modules, %zd symbols)\n",
1553 depmod
->modules
.count
, hash_get_count(depmod
->symbols
));
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
;
1560 if (mod
->dep_sym_list
== NULL
) {
1561 DBG("ignoring %s: no dependency symbols\n", mod
->path
);
1565 depmod_load_module_dependencies(depmod
, mod
);
1568 DBG("loaded dependencies (%zd modules, %zd symbols)\n",
1569 depmod
->modules
.count
, hash_get_count(depmod
->symbols
));
1574 static int dep_cmp(const void *pa
, const void *pb
)
1576 const struct mod
*a
= *(const struct mod
**)pa
;
1577 const struct mod
*b
= *(const struct mod
**)pb
;
1578 if (a
->dep_loop
== b
->dep_loop
)
1579 return a
->dep_sort_idx
- b
->dep_sort_idx
;
1580 else if (a
->dep_loop
)
1582 else if (b
->dep_loop
)
1584 return a
->dep_sort_idx
- b
->dep_sort_idx
;
1587 static void depmod_sort_dependencies(struct depmod
*depmod
)
1589 struct mod
**itr
, **itr_end
;
1590 itr
= (struct mod
**)depmod
->modules
.array
;
1591 itr_end
= itr
+ depmod
->modules
.count
;
1592 for (; itr
< itr_end
; itr
++) {
1593 struct mod
*m
= *itr
;
1594 if (m
->deps
.count
> 1)
1595 array_sort(&m
->deps
, dep_cmp
);
1599 static int depmod_calculate_dependencies(struct depmod
*depmod
)
1601 const struct mod
**itrm
;
1602 uint16_t *users
, *roots
, *sorted
;
1603 uint16_t i
, n_roots
= 0, n_sorted
= 0, n_mods
= depmod
->modules
.count
;
1605 users
= malloc(sizeof(uint16_t) * n_mods
* 3);
1608 roots
= users
+ n_mods
;
1609 sorted
= roots
+ n_mods
;
1611 DBG("calculate dependencies and ordering (%zd modules)\n", n_mods
);
1613 assert(depmod
->modules
.count
< UINT16_MAX
);
1615 /* populate modules users (how many modules uses it) */
1616 itrm
= (const struct mod
**)depmod
->modules
.array
;
1617 for (i
= 0; i
< n_mods
; i
++, itrm
++) {
1618 const struct mod
*m
= *itrm
;
1619 users
[i
] = m
->users
;
1620 if (users
[i
] == 0) {
1626 /* topological sort (outputs modules without users first) */
1627 while (n_roots
> 0) {
1628 const struct mod
**itr_dst
, **itr_dst_end
;
1630 uint16_t src_idx
= roots
[--n_roots
];
1632 src
= depmod
->modules
.array
[src_idx
];
1633 src
->dep_sort_idx
= n_sorted
;
1634 sorted
[n_sorted
] = src_idx
;
1637 itr_dst
= (const struct mod
**)src
->deps
.array
;
1638 itr_dst_end
= itr_dst
+ src
->deps
.count
;
1639 for (; itr_dst
< itr_dst_end
; itr_dst
++) {
1640 const struct mod
*dst
= *itr_dst
;
1641 uint16_t dst_idx
= dst
->idx
;
1642 assert(users
[dst_idx
] > 0);
1644 if (users
[dst_idx
] == 0) {
1645 roots
[n_roots
] = dst_idx
;
1651 if (n_sorted
< n_mods
) {
1652 WRN("found %hu modules in dependency cycles!\n",
1654 for (i
= 0; i
< n_mods
; i
++) {
1658 m
= depmod
->modules
.array
[i
];
1659 WRN("%s in dependency cycle!\n", m
->path
);
1661 m
->dep_sort_idx
= INT32_MAX
;
1662 depmod
->dep_loops
++;
1666 depmod_sort_dependencies(depmod
);
1668 DBG("calculated dependencies and ordering (%u loops, %zd modules)\n",
1669 depmod
->dep_loops
, n_mods
);
1675 static int depmod_load(struct depmod
*depmod
)
1679 err
= depmod_load_modules(depmod
);
1683 err
= depmod_load_dependencies(depmod
);
1687 err
= depmod_calculate_dependencies(depmod
);
1694 static size_t mod_count_all_dependencies(const struct mod
*mod
)
1696 size_t i
, count
= 0;
1697 for (i
= 0; i
< mod
->deps
.count
; i
++) {
1698 const struct mod
*d
= mod
->deps
.array
[i
];
1699 count
+= 1 + mod_count_all_dependencies(d
);
1704 static int mod_fill_all_unique_dependencies(const struct mod
*mod
, const struct mod
**deps
, size_t n_deps
, size_t *last
)
1708 for (i
= 0; i
< mod
->deps
.count
; i
++) {
1709 const struct mod
*d
= mod
->deps
.array
[i
];
1713 for (j
= 0; j
< *last
; j
++) {
1723 if (*last
>= n_deps
)
1727 err
= mod_fill_all_unique_dependencies(d
, deps
, n_deps
, last
);
1734 static const struct mod
**mod_get_all_sorted_dependencies(const struct mod
*mod
, size_t *n_deps
)
1736 const struct mod
**deps
;
1739 *n_deps
= mod_count_all_dependencies(mod
);
1743 deps
= malloc(sizeof(struct mod
*) * (*n_deps
));
1747 if (mod_fill_all_unique_dependencies(mod
, deps
, *n_deps
, &last
) < 0) {
1752 qsort(deps
, last
, sizeof(struct mod
*), dep_cmp
);
1757 static inline const char *mod_get_compressed_path(const struct mod
*mod
)
1759 if (mod
->relpath
!= NULL
)
1760 return mod
->relpath
;
1764 static int output_deps(struct depmod
*depmod
, FILE *out
)
1768 for (i
= 0; i
< depmod
->modules
.count
; i
++) {
1769 const struct mod
**deps
, *mod
= depmod
->modules
.array
[i
];
1770 const char *p
= mod_get_compressed_path(mod
);
1773 if (mod
->dep_loop
) {
1774 DBG("Ignored %s due dependency loops\n", p
);
1778 fprintf(out
, "%s:", p
);
1780 if (mod
->deps
.count
== 0)
1783 deps
= mod_get_all_sorted_dependencies(mod
, &n_deps
);
1785 ERR("could not get all sorted dependencies of %s\n", p
);
1789 for (j
= 0; j
< n_deps
; j
++) {
1790 const struct mod
*d
= deps
[j
];
1792 DBG("Ignored %s (dependency of %s) "
1793 "due dependency loops\n",
1794 mod_get_compressed_path(d
), p
);
1797 fprintf(out
, " %s", mod_get_compressed_path(d
));
1807 static int output_deps_bin(struct depmod
*depmod
, FILE *out
)
1809 struct index_node
*idx
;
1815 idx
= index_create();
1819 for (i
= 0; i
< depmod
->modules
.count
; i
++) {
1820 const struct mod
**deps
, *mod
= depmod
->modules
.array
[i
];
1821 const char *p
= mod_get_compressed_path(mod
);
1823 size_t j
, n_deps
, linepos
, linelen
, slen
;
1826 if (mod
->dep_loop
) {
1827 DBG("Ignored %s due dependency loops\n", p
);
1831 deps
= mod_get_all_sorted_dependencies(mod
, &n_deps
);
1832 if (deps
== NULL
&& n_deps
> 0) {
1833 ERR("could not get all sorted dependencies of %s\n", p
);
1837 linelen
= strlen(p
) + 1;
1838 for (j
= 0; j
< n_deps
; j
++) {
1839 const struct mod
*d
= deps
[j
];
1841 DBG("Ignored %s (dependency of %s) "
1842 "due dependency loops\n",
1843 mod_get_compressed_path(d
), p
);
1846 linelen
+= 1 + strlen(mod_get_compressed_path(d
));
1849 line
= malloc(linelen
+ 1);
1852 ERR("modules.deps.bin: out of memory\n");
1858 memcpy(line
+ linepos
, p
, slen
);
1860 line
[linepos
] = ':';
1863 for (j
= 0; j
< n_deps
; j
++) {
1864 const struct mod
*d
= deps
[j
];
1868 line
[linepos
] = ' ';
1871 dp
= mod_get_compressed_path(d
);
1873 memcpy(line
+ linepos
, dp
, slen
);
1876 line
[linepos
] = '\0';
1878 duplicate
= index_insert(idx
, mod
->modname
, line
, mod
->idx
);
1879 if (duplicate
&& depmod
->cfg
->warn_dups
)
1880 WRN("duplicate module deps:\n%s\n", line
);
1885 index_write(idx
, out
);
1891 static int output_aliases(struct depmod
*depmod
, FILE *out
)
1895 fputs("# Aliases extracted from modules themselves.\n", out
);
1897 for (i
= 0; i
< depmod
->modules
.count
; i
++) {
1898 const struct mod
*mod
= depmod
->modules
.array
[i
];
1899 struct kmod_list
*l
;
1901 kmod_list_foreach(l
, mod
->info_list
) {
1902 const char *key
= kmod_module_info_get_key(l
);
1903 const char *value
= kmod_module_info_get_value(l
);
1905 if (!streq(key
, "alias"))
1908 fprintf(out
, "alias %s %s\n", value
, mod
->modname
);
1915 static int output_aliases_bin(struct depmod
*depmod
, FILE *out
)
1918 struct index_node
*idx
;
1924 idx
= index_create();
1928 for (i
= 0; i
< depmod
->modules
.count
; i
++) {
1929 const struct mod
*mod
= depmod
->modules
.array
[i
];
1930 struct kmod_list
*l
;
1932 kmod_list_foreach(l
, mod
->info_list
) {
1933 const char *key
= kmod_module_info_get_key(l
);
1934 const char *value
= kmod_module_info_get_value(l
);
1938 if (!streq(key
, "alias"))
1941 alias
= underscores2(value
, buf
, sizeof(buf
));
1945 duplicate
= index_insert(idx
, alias
, mod
->modname
,
1947 if (duplicate
&& depmod
->cfg
->warn_dups
)
1948 WRN("duplicate module alias:\n%s %s\n",
1949 alias
, mod
->modname
);
1953 index_write(idx
, out
);
1959 static int output_softdeps(struct depmod
*depmod
, FILE *out
)
1963 fputs("# Soft dependencies extracted from modules themselves.\n", out
);
1964 fputs("# Copy, with a .conf extension, to /etc/modprobe.d to use "
1965 "it with modprobe.\n", out
);
1967 for (i
= 0; i
< depmod
->modules
.count
; i
++) {
1968 const struct mod
*mod
= depmod
->modules
.array
[i
];
1969 struct kmod_list
*l
;
1971 kmod_list_foreach(l
, mod
->info_list
) {
1972 const char *key
= kmod_module_info_get_key(l
);
1973 const char *value
= kmod_module_info_get_value(l
);
1975 if (!streq(key
, "softdep"))
1978 fprintf(out
, "softdep %s %s\n", mod
->modname
, value
);
1985 static int output_symbols(struct depmod
*depmod
, FILE *out
)
1987 struct hash_iter iter
;
1990 fputs("# Aliases for symbols, used by symbol_request().\n", out
);
1992 hash_iter_init(depmod
->symbols
, &iter
);
1994 while (hash_iter_next(&iter
, NULL
, &v
)) {
1995 const struct symbol
*sym
= v
;
1996 if (sym
->owner
== NULL
)
1999 fprintf(out
, "alias symbol:%s %s\n",
2000 sym
->name
, sym
->owner
->modname
);
2006 static int output_symbols_bin(struct depmod
*depmod
, FILE *out
)
2008 struct index_node
*idx
;
2010 size_t baselen
= sizeof("symbol:") - 1;
2011 struct hash_iter iter
;
2017 idx
= index_create();
2021 memcpy(alias
, "symbol:", baselen
);
2022 hash_iter_init(depmod
->symbols
, &iter
);
2024 while (hash_iter_next(&iter
, NULL
, &v
)) {
2026 const struct symbol
*sym
= v
;
2028 if (sym
->owner
== NULL
)
2031 strcpy(alias
+ baselen
, sym
->name
);
2032 duplicate
= index_insert(idx
, alias
, sym
->owner
->modname
,
2035 if (duplicate
&& depmod
->cfg
->warn_dups
)
2036 WRN("duplicate module syms:\n%s %s\n",
2037 alias
, sym
->owner
->modname
);
2040 index_write(idx
, out
);
2046 static int output_builtin_bin(struct depmod
*depmod
, FILE *out
)
2049 struct index_node
*idx
;
2050 char infile
[PATH_MAX
], line
[PATH_MAX
], modname
[PATH_MAX
];
2055 snprintf(infile
, sizeof(infile
), "%s/modules.builtin",
2056 depmod
->cfg
->dirname
);
2057 in
= fopen(infile
, "r");
2059 WRN("could not open %s: %m\n", infile
);
2063 idx
= index_create();
2069 while (fgets(line
, sizeof(line
), in
) != NULL
) {
2070 if (!isalpha(line
[0])) {
2071 ERR("Invalid modules.builtin line: %s\n", line
);
2075 path_to_modname(line
, modname
, NULL
);
2076 index_insert(idx
, modname
, "", 0);
2079 index_write(idx
, out
);
2086 static int output_devname(struct depmod
*depmod
, FILE *out
)
2090 fputs("# Device nodes to trigger on-demand module loading.\n", out
);
2092 for (i
= 0; i
< depmod
->modules
.count
; i
++) {
2093 const struct mod
*mod
= depmod
->modules
.array
[i
];
2094 struct kmod_list
*l
;
2095 const char *devname
= NULL
;
2097 unsigned int major
= 0, minor
= 0;
2099 kmod_list_foreach(l
, mod
->info_list
) {
2100 const char *key
= kmod_module_info_get_key(l
);
2101 const char *value
= kmod_module_info_get_value(l
);
2102 unsigned int maj
, min
;
2104 if (!streq(key
, "alias"))
2107 if (strstartswith(value
, "devname:"))
2108 devname
= value
+ sizeof("devname:") - 1;
2109 else if (sscanf(value
, "char-major-%u-%u",
2114 } else if (sscanf(value
, "block-major-%u-%u",
2121 if (type
!= '\0' && devname
!= NULL
) {
2122 fprintf(out
, "%s %s %c%u:%u\n", mod
->modname
,
2123 devname
, type
, major
, minor
);
2132 static int depmod_output(struct depmod
*depmod
, FILE *out
)
2134 static const struct depfile
{
2136 int (*cb
)(struct depmod
*depmod
, FILE *out
);
2137 } *itr
, depfiles
[] = {
2138 { "modules.dep", output_deps
},
2139 { "modules.dep.bin", output_deps_bin
},
2140 { "modules.alias", output_aliases
},
2141 { "modules.alias.bin", output_aliases_bin
},
2142 { "modules.softdep", output_softdeps
},
2143 { "modules.symbols", output_symbols
},
2144 { "modules.symbols.bin", output_symbols_bin
},
2145 { "modules.builtin.bin", output_builtin_bin
},
2146 { "modules.devname", output_devname
},
2149 const char *dname
= depmod
->cfg
->dirname
;
2155 dfd
= open(dname
, O_RDONLY
);
2158 CRIT("could not open directory %s: %m\n", dname
);
2163 for (itr
= depfiles
; itr
->name
!= NULL
; itr
++) {
2165 char tmp
[NAME_MAX
] = "";
2169 int flags
= O_CREAT
| O_TRUNC
| O_WRONLY
;
2173 snprintf(tmp
, sizeof(tmp
), "%s.tmp", itr
->name
);
2174 fd
= openat(dfd
, tmp
, flags
, mode
);
2176 ERR("openat(%s, %s, %o, %o): %m\n",
2177 dname
, tmp
, flags
, mode
);
2180 fp
= fdopen(fd
, "wb");
2182 ERR("fdopen(%d=%s/%s): %m\n", fd
, dname
, tmp
);
2188 r
= itr
->cb(depmod
, fp
);
2192 ferr
= ferror(fp
) | fclose(fp
);
2195 if (unlinkat(dfd
, tmp
, 0) != 0)
2196 ERR("unlinkat(%s, %s): %m\n", dname
, tmp
);
2198 ERR("Could not write index '%s': %s\n", itr
->name
,
2204 unlinkat(dfd
, itr
->name
, 0);
2205 if (renameat(dfd
, tmp
, dfd
, itr
->name
) != 0) {
2207 CRIT("renameat(%s, %s, %s, %s): %m\n",
2208 dname
, tmp
, dname
, itr
->name
);
2214 ERR("Could not create index '%s'. Output is truncated: %s\n",
2215 itr
->name
, strerror(-err
));
2226 static void depmod_add_fake_syms(struct depmod
*depmod
)
2228 /* __this_module is magic inserted by kernel loader. */
2229 depmod_symbol_add(depmod
, "__this_module", 0, NULL
);
2230 /* On S390, this is faked up too */
2231 depmod_symbol_add(depmod
, "_GLOBAL_OFFSET_TABLE_", 0, NULL
);
2234 static int depmod_load_symvers(struct depmod
*depmod
, const char *filename
)
2238 unsigned int linenum
= 0;
2240 fp
= fopen(filename
, "r");
2243 DBG("load symvers: %s: %m\n", filename
);
2246 DBG("load symvers: %s\n", filename
);
2248 /* eg. "0xb352177e\tfind_first_bit\tvmlinux\tEXPORT_SYMBOL" */
2249 while (fgets(line
, sizeof(line
), fp
) != NULL
) {
2250 const char *ver
, *sym
, *where
;
2256 ver
= strtok(line
, " \t");
2257 sym
= strtok(NULL
, " \t");
2258 where
= strtok(NULL
, " \t");
2259 if (!ver
|| !sym
|| !where
)
2262 if (!streq(where
, "vmlinux"))
2265 crc
= strtoull(ver
, &verend
, 16);
2266 if (verend
[0] != '\0') {
2267 ERR("%s:%u Invalid symbol version %s: %m\n",
2268 filename
, linenum
, ver
);
2272 depmod_symbol_add(depmod
, sym
, crc
, NULL
);
2274 depmod_add_fake_syms(depmod
);
2276 DBG("loaded symvers: %s\n", filename
);
2282 static int depmod_load_system_map(struct depmod
*depmod
, const char *filename
)
2284 const char ksymstr
[] = "__ksymtab_";
2285 const size_t ksymstr_len
= sizeof(ksymstr
) - 1;
2288 unsigned int linenum
= 0;
2290 fp
= fopen(filename
, "r");
2293 DBG("load System.map: %s: %m\n", filename
);
2296 DBG("load System.map: %s\n", filename
);
2298 /* eg. c0294200 R __ksymtab_devfs_alloc_devnum */
2299 while (fgets(line
, sizeof(line
), fp
) != NULL
) {
2304 p
= strchr(line
, ' ');
2306 goto invalid_syntax
;
2310 goto invalid_syntax
;
2313 /* Covers gpl-only and normal symbols. */
2314 if (strncmp(p
, ksymstr
, ksymstr_len
) != 0)
2317 end
= strchr(p
, '\n');
2321 depmod_symbol_add(depmod
, p
+ ksymstr_len
, 0, NULL
);
2325 ERR("%s:%u: invalid line: %s\n", filename
, linenum
, line
);
2327 depmod_add_fake_syms(depmod
);
2329 DBG("loaded System.map: %s\n", filename
);
2336 static int depfile_up_to_date_dir(DIR *d
, time_t mtime
, size_t baselen
, char *path
)
2339 int err
= 1, dfd
= dirfd(d
);
2341 while ((de
= readdir(d
)) != NULL
) {
2342 const char *name
= de
->d_name
;
2346 if (name
[0] == '.' && (name
[1] == '\0' ||
2347 (name
[1] == '.' && name
[2] == '\0')))
2349 if (streq(name
, "build") || streq(name
, "source"))
2351 namelen
= strlen(name
);
2352 if (baselen
+ namelen
+ 2 >= PATH_MAX
) {
2353 path
[baselen
] = '\0';
2354 ERR("path is too long %s%s %zd\n", path
, name
);
2358 if (fstatat(dfd
, name
, &st
, 0) < 0) {
2359 ERR("fstatat(%d, %s): %m\n", dfd
, name
);
2363 if (S_ISDIR(st
.st_mode
)) {
2366 memcpy(path
+ baselen
, name
, namelen
+ 1);
2367 if (baselen
+ namelen
+ 2 + NAME_MAX
>= PATH_MAX
) {
2368 ERR("directory path is too long %s\n", path
);
2371 fd
= openat(dfd
, name
, O_RDONLY
);
2373 ERR("openat(%d, %s, O_RDONLY): %m\n",
2377 subdir
= fdopendir(fd
);
2378 if (subdir
== NULL
) {
2379 ERR("fdopendir(%d): %m\n", fd
);
2383 path
[baselen
+ namelen
] = '/';
2384 path
[baselen
+ namelen
+ 1] = '\0';
2385 err
= depfile_up_to_date_dir(subdir
, mtime
,
2386 baselen
+ namelen
+ 1,
2389 } else if (S_ISREG(st
.st_mode
)) {
2390 if (!path_ends_with_kmod_ext(path
, namelen
))
2392 memcpy(path
+ baselen
, name
, namelen
+ 1);
2393 err
= st
.st_mtime
<= mtime
;
2395 DBG("%s %"PRIu64
" is newer than %"PRIu64
"\n",
2396 path
, (uint64_t)st
.st_mtime
,
2400 ERR("unsupported file type %s: %o\n",
2401 path
, st
.st_mode
& S_IFMT
);
2406 break; /* outdated! */
2408 path
[baselen
+ namelen
] = '\0';
2409 ERR("failed %s: %s\n", path
, strerror(-err
));
2410 err
= 1; /* ignore errors */
2417 /* uptodate: 1, outdated: 0, errors < 0 */
2418 static int depfile_up_to_date(const char *dirname
)
2420 char path
[PATH_MAX
];
2421 DIR *d
= opendir(dirname
);
2427 ERR("could not open directory %s: %m\n", dirname
);
2431 if (fstatat(dirfd(d
), "modules.dep", &st
, 0) != 0) {
2433 ERR("could not fstatat(%s, modules.dep): %m\n", dirname
);
2438 baselen
= strlen(dirname
);
2439 memcpy(path
, dirname
, baselen
);
2440 path
[baselen
] = '/';
2442 path
[baselen
] = '\0';
2444 err
= depfile_up_to_date_dir(d
, st
.st_mtime
, baselen
, path
);
2449 static int is_version_number(const char *version
)
2451 unsigned int d1
, d2
;
2452 return (sscanf(version
, "%u.%u", &d1
, &d2
) == 2);
2455 static int do_depmod(int argc
, char *argv
[])
2458 int err
= 0, all
= 0, maybe_all
= 0, n_config_paths
= 0;
2460 const char **config_paths
= NULL
;
2461 const char *system_map
= NULL
;
2462 const char *module_symvers
= NULL
;
2463 const char *null_kmod_config
= NULL
;
2465 struct kmod_ctx
*ctx
= NULL
;
2467 struct depmod depmod
;
2469 memset(&cfg
, 0, sizeof(cfg
));
2470 memset(&depmod
, 0, sizeof(depmod
));
2474 c
= getopt_long(argc
, argv
, cmdopts_s
, cmdopts
, &idx
);
2485 root
= path_make_absolute_cwd(optarg
);
2488 size_t bytes
= sizeof(char *) * (n_config_paths
+ 2);
2489 void *tmp
= realloc(config_paths
, bytes
);
2491 fputs("Error: out-of-memory\n", stderr
);
2492 goto cmdline_failed
;
2495 config_paths
[n_config_paths
] = optarg
;
2497 config_paths
[n_config_paths
] = NULL
;
2501 module_symvers
= optarg
;
2502 cfg
.check_symvers
= 1;
2505 system_map
= optarg
;
2508 cfg
.print_unknown
= 1;
2517 if (optarg
[1] != '\0') {
2518 CRIT("-P only takes a single char\n");
2519 goto cmdline_failed
;
2521 cfg
.sym_prefix
= optarg
[0];
2531 WRN("Ignored deprecated option --%s\n",
2534 WRN("Ignored deprecated option -%c\n", c
);
2540 return EXIT_SUCCESS
;
2542 puts(PACKAGE
" version " VERSION
);
2544 return EXIT_SUCCESS
;
2546 goto cmdline_failed
;
2548 ERR("unexpected getopt_long() value '%c'.\n", c
);
2549 goto cmdline_failed
;
2553 if (optind
< argc
&& is_version_number(argv
[optind
])) {
2554 cfg
.kversion
= argv
[optind
];
2557 if (uname(&un
) < 0) {
2558 CRIT("uname() failed: %s\n", strerror(errno
));
2559 goto cmdline_failed
;
2561 cfg
.kversion
= un
.release
;
2564 cfg
.dirnamelen
= snprintf(cfg
.dirname
, PATH_MAX
,
2565 "%s/lib/modules/%s",
2566 root
== NULL
? "" : root
, cfg
.kversion
);
2574 /* ignore up-to-date errors (< 0) */
2575 if (depfile_up_to_date(cfg
.dirname
) == 1) {
2576 DBG("%s/modules.dep is up to date!\n", cfg
.dirname
);
2579 DBG("%s/modules.dep is outdated, do -a\n", cfg
.dirname
);
2583 ctx
= kmod_new(cfg
.dirname
, &null_kmod_config
);
2585 CRIT("kmod_new(\"%s\", {NULL}) failed: %m\n", cfg
.dirname
);
2586 goto cmdline_failed
;
2589 log_setup_kmod_log(ctx
, verbose
);
2591 err
= depmod_init(&depmod
, &cfg
, ctx
);
2593 CRIT("depmod_init: %s\n", strerror(-err
));
2594 goto depmod_init_failed
;
2596 ctx
= NULL
; /* owned by depmod */
2598 if (module_symvers
!= NULL
) {
2599 err
= depmod_load_symvers(&depmod
, module_symvers
);
2601 CRIT("could not load %s: %s\n", module_symvers
,
2603 goto cmdline_failed
;
2605 } else if (system_map
!= NULL
) {
2606 err
= depmod_load_system_map(&depmod
, system_map
);
2608 CRIT("could not load %s: %s\n", system_map
,
2610 goto cmdline_failed
;
2612 } else if (cfg
.print_unknown
) {
2613 WRN("-e needs -E or -F\n");
2614 cfg
.print_unknown
= 0;
2618 err
= cfg_load(&cfg
, config_paths
);
2620 CRIT("could not load configuration files\n");
2621 goto cmdline_modules_failed
;
2623 err
= depmod_modules_search(&depmod
);
2625 CRIT("could not search modules: %s\n", strerror(-err
));
2626 goto cmdline_modules_failed
;
2631 for (i
= optind
; i
< argc
; i
++) {
2632 const char *path
= argv
[i
];
2633 struct kmod_module
*mod
;
2635 if (path
[0] != '/') {
2636 CRIT("%s: not absolute path.\n", path
);
2637 goto cmdline_modules_failed
;
2640 err
= kmod_module_new_from_path(depmod
.ctx
, path
, &mod
);
2642 CRIT("could not create module %s: %s\n",
2643 path
, strerror(-err
));
2644 goto cmdline_modules_failed
;
2647 err
= depmod_module_add(&depmod
, mod
);
2649 CRIT("could not add module %s: %s\n",
2650 path
, strerror(-err
));
2651 kmod_module_unref(mod
);
2652 goto cmdline_modules_failed
;
2657 err
= depmod_modules_build_array(&depmod
);
2659 CRIT("could not build module array: %s\n",
2661 goto cmdline_modules_failed
;
2664 depmod_modules_sort(&depmod
);
2665 err
= depmod_load(&depmod
);
2667 goto cmdline_modules_failed
;
2669 err
= depmod_output(&depmod
, out
);
2672 depmod_shutdown(&depmod
);
2675 return err
>= 0 ? EXIT_SUCCESS
: EXIT_FAILURE
;
2677 cmdline_modules_failed
:
2678 depmod_shutdown(&depmod
);
2686 return EXIT_FAILURE
;
2689 const struct kmod_cmd kmod_cmd_compat_depmod
= {
2692 .help
= "compat depmod command",