2 * kmod-depmod - calculate modules.dep using libkmod.
4 * Copyright (C) 2011 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/>.
28 #include <sys/utsname.h>
35 #include "libkmod-hash.h"
36 #include "libkmod-array.h"
38 #define streq(a, b) (strcmp(a, b) == 0)
39 #define strstartswith(a, b) (strncmp(a, b, strlen(b)) == 0)
41 #define DEFAULT_VERBOSE LOG_WARNING
42 static int verbose
= DEFAULT_VERBOSE
;
44 static const struct kmod_ext
{
48 {".ko", sizeof(".ko") - 1},
50 {".ko.gz", sizeof(".ko.gz") - 1},
53 {".ko.xz", sizeof(".ko.xz") - 1},
58 static const char CFG_BUILTIN_KEY
[] = "built-in";
59 static const char *default_cfg_paths
[] = {
61 SYSCONFDIR
"/depmod.d",
62 ROOTPREFIX
"/lib/depmod.d",
66 static const char cmdopts_s
[] = "aAb:C:E:F:euqrvnP:wmVh";
67 static const struct option cmdopts
[] = {
68 {"all", no_argument
, 0, 'a'},
69 {"quick", no_argument
, 0, 'A'},
70 {"basedir", required_argument
, 0, 'b'},
71 {"config", required_argument
, 0, 'C'},
72 {"symvers", required_argument
, 0, 'E'},
73 {"filesyms", required_argument
, 0, 'F'},
74 {"errsyms", no_argument
, 0, 'e'},
75 {"unresolved-error", no_argument
, 0, 'u'}, /* deprecated */
76 {"quiet", no_argument
, 0, 'q'}, /* deprecated */
77 {"root", no_argument
, 0, 'r'}, /* deprecated */
78 {"verbose", no_argument
, 0, 'v'},
79 {"show", no_argument
, 0, 'n'},
80 {"dry-run", no_argument
, 0, 'n'},
81 {"symbol-prefix", no_argument
, 0, 'P'},
82 {"warn", no_argument
, 0, 'w'},
83 {"map", no_argument
, 0, 'm'}, /* deprecated */
84 {"version", no_argument
, 0, 'V'},
85 {"help", no_argument
, 0, 'h'},
89 static void help(const char *progname
)
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-v, --verbose Enable verbose mode\n"
106 "\t-w, --warn Warn on duplicates\n"
107 "\t-V, --version show version\n"
108 "\t-h, --help show this help\n"
110 "The following options are useful for people managing distributions:\n"
111 "\t-b, --basedir=DIR Use an image of a module tree.\n"
112 "\t-F, --filesyms=FILE Use the file instead of the\n"
113 "\t current kernel symbols.\n"
114 "\t-E, --symvers=FILE Use Module.symvers file to check\n"
115 "\t symbol versions.\n",
119 static inline void _show(const char *fmt
, ...)
123 if (verbose
<= DEFAULT_VERBOSE
)
127 vfprintf(stdout
, fmt
, args
);
132 static inline void _log(int prio
, const char *fmt
, ...)
134 const char *prioname
;
142 if (vasprintf(&msg
, fmt
, args
) < 0)
156 prioname
= "WARNING";
168 snprintf(buf
, sizeof(buf
), "LOG-%03d", prio
);
172 fprintf(stderr
, "%s: %s", prioname
, msg
);
175 if (prio
<= LOG_CRIT
)
178 #define CRIT(...) _log(LOG_CRIT, __VA_ARGS__)
179 #define ERR(...) _log(LOG_ERR, __VA_ARGS__)
180 #define WRN(...) _log(LOG_WARNING, __VA_ARGS__)
181 #define INF(...) _log(LOG_INFO, __VA_ARGS__)
182 #define DBG(...) _log(LOG_DEBUG, __VA_ARGS__)
183 #define SHOW(...) _show(__VA_ARGS__)
186 /* binary index write *************************************************/
187 #include <arpa/inet.h>
189 /* BEGIN: code from module-init-tools/index.c just modified to compile here.
191 * Original copyright:
192 * index.c: module index file shared functions for modprobe and depmod
193 * Copyright (C) 2008 Alan Jenkins <alan-jenkins@tuffmail.co.uk>.
195 * These programs are free software; you can redistribute it and/or modify
196 * it under the terms of the GNU General Public License as published by
197 * the Free Software Foundation; either version 2 of the License, or
198 * (at your option) any later version.
200 * This program is distributed in the hope that it will be useful,
201 * but WITHOUT ANY WARRANTY; without even the implied warranty of
202 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
203 * GNU General Public License for more details.
205 * You should have received a copy of the GNU General Public License
206 * along with these programs. If not, see <http://www.gnu.org/licenses/>.
209 /* Integers are stored as 32 bit unsigned in "network" order, i.e. MSB first.
210 All files start with a magic number.
212 Magic spells "BOOTFAST". Second one used on newer versioned binary files.
214 /* #define INDEX_MAGIC_OLD 0xB007FA57 */
215 #define INDEX_MAGIC 0xB007F457
217 /* We use a version string to keep track of changes to the binary format
218 * This is stored in the form: INDEX_MAJOR (hi) INDEX_MINOR (lo) just in
219 * case we ever decide to have minor changes that are not incompatible.
222 #define INDEX_VERSION_MAJOR 0x0002
223 #define INDEX_VERSION_MINOR 0x0001
224 #define INDEX_VERSION ((INDEX_VERSION_MAJOR<<16)|INDEX_VERSION_MINOR)
226 /* The index file maps keys to values. Both keys and values are ASCII strings.
227 Each key can have multiple values. Values are sorted by an integer priority.
229 The reader also implements a wildcard search (including range expressions)
230 where the keys in the index are treated as patterns.
231 This feature is required for module aliases.
234 /* Implementation is based on a radix tree, or "trie".
235 Each arc from parent to child is labelled with a character.
236 Each path from the root represents a string.
238 == Example strings ==
248 * Marked node, representing a key and it's values.
259 Naive implementations tend to be very space inefficient; child pointers
260 are stored in arrays indexed by character, but most child pointers are null.
262 Our implementation uses a scheme described by Wikipedia as a Patrica trie,
264 "easiest to understand as a space-optimized trie where
265 each node with only one child is merged with its child"
276 We still use arrays of child pointers indexed by a single character;
277 the remaining characters of the label are stored as a "prefix" in the child.
279 The paper describing the original Patrica trie works on individiual bits -
280 each node has a maximum of two children, which increases space efficiency.
281 However for this application it is simpler to use the ASCII character set.
282 Since the index file is read-only, it can be compressed by omitting null
283 child pointers at the start and end of arrays.
286 #define INDEX_PRIORITY_MIN UINT32_MAX
289 struct index_value
*next
;
290 unsigned int priority
;
294 /* In-memory index (depmod only) */
296 #define INDEX_CHILDMAX 128
298 char *prefix
; /* path compression */
299 struct index_value
*values
;
300 unsigned char first
; /* range of child nodes */
302 struct index_node
*children
[INDEX_CHILDMAX
]; /* indexed by character */
307 uint32_t magic = INDEX_MAGIC;
308 uint32_t version = INDEX_VERSION;
309 uint32_t root_offset;
311 (node_offset & INDEX_NODE_MASK) specifies the file offset of nodes:
313 char[] prefix; // nul terminated
317 uint32_t children[last - first + 1];
319 uint32_t value_count;
322 char[] value; // nul terminated
323 } values[value_count];
325 (node_offset & INDEX_NODE_FLAGS) indicates which fields are present.
326 Empty prefixes are ommitted, leaf nodes omit the three child-related fields.
328 This could be optimised further by adding a sparse child format
329 (indicated using a new flag).
332 /* Format of node offsets within index file */
334 INDEX_NODE_FLAGS
= 0xF0000000, /* Flags in high nibble */
335 INDEX_NODE_PREFIX
= 0x80000000,
336 INDEX_NODE_VALUES
= 0x40000000,
337 INDEX_NODE_CHILDS
= 0x20000000,
339 INDEX_NODE_MASK
= 0x0FFFFFFF, /* Offset value */
342 static struct index_node
*index_create(void)
344 struct index_node
*node
;
346 node
= NOFAIL(calloc(sizeof(struct index_node
), 1));
347 node
->prefix
= NOFAIL(strdup(""));
348 node
->first
= INDEX_CHILDMAX
;
353 static void index_values_free(struct index_value
*values
)
356 struct index_value
*value
= values
;
358 values
= value
->next
;
363 static void index_destroy(struct index_node
*node
)
367 for (c
= node
->first
; c
<= node
->last
; c
++) {
368 struct index_node
*child
= node
->children
[c
];
371 index_destroy(child
);
373 index_values_free(node
->values
);
378 static void index__checkstring(const char *str
)
382 for (i
= 0; str
[i
]; i
++) {
385 if (ch
>= INDEX_CHILDMAX
)
386 CRIT("Module index: bad character '%c'=0x%x - only 7-bit ASCII is supported:"
387 "\n%s\n", (char) ch
, (int) ch
, str
);
391 static int index_add_value(struct index_value
**values
,
392 const char *value
, unsigned int priority
)
394 struct index_value
*v
;
398 /* report the presence of duplicate values */
399 for (v
= *values
; v
; v
= v
->next
) {
400 if (streq(v
->value
, value
))
404 /* find position to insert value */
405 while (*values
&& (*values
)->priority
< priority
)
406 values
= &(*values
)->next
;
409 v
= NOFAIL(calloc(sizeof(struct index_value
) + len
+ 1, 1));
411 v
->priority
= priority
;
412 memcpy(v
->value
, value
, len
+ 1);
418 static int index_insert(struct index_node
*node
, const char *key
,
419 const char *value
, unsigned int priority
)
421 int i
= 0; /* index within str */
424 index__checkstring(key
);
425 index__checkstring(value
);
428 int j
; /* index within node->prefix */
430 /* Ensure node->prefix is a prefix of &str[i].
431 If it is not already, then we must split node. */
432 for (j
= 0; node
->prefix
[j
]; j
++) {
433 ch
= node
->prefix
[j
];
435 if (ch
!= key
[i
+j
]) {
436 char *prefix
= node
->prefix
;
437 struct index_node
*n
;
439 /* New child is copy of node with prefix[j+1..N] */
440 n
= NOFAIL(calloc(sizeof(struct index_node
), 1));
441 memcpy(n
, node
, sizeof(struct index_node
));
442 n
->prefix
= NOFAIL(strdup(&prefix
[j
+1]));
444 /* Parent has prefix[0..j], child at prefix[j] */
445 memset(node
, 0, sizeof(struct index_node
));
447 node
->prefix
= prefix
;
450 node
->children
[ch
] = n
;
455 /* j is now length of node->prefix */
460 return index_add_value(&node
->values
, value
, priority
);
462 if (!node
->children
[ch
]) {
463 struct index_node
*child
;
465 if (ch
< node
->first
)
469 node
->children
[ch
] = NOFAIL(calloc(sizeof(struct index_node
), 1));
471 child
= node
->children
[ch
];
472 child
->prefix
= NOFAIL(strdup(&key
[i
+1]));
473 child
->first
= INDEX_CHILDMAX
;
474 index_add_value(&child
->values
, value
, priority
);
479 /* Descend into child node and continue */
480 node
= node
->children
[ch
];
485 static int index__haschildren(const struct index_node
*node
)
487 return node
->first
< INDEX_CHILDMAX
;
490 /* Recursive post-order traversal
492 Pre-order would make for better read-side buffering / readahead / caching.
493 (post-order means you go backwards in the file as you descend the tree).
494 However, index reading is already fast enough.
495 Pre-order is simpler for writing, and depmod is already slow.
497 static uint32_t index_write__node(const struct index_node
*node
, FILE *out
)
499 uint32_t *child_offs
= NULL
;
506 /* Write children and save their offsets */
507 if (index__haschildren(node
)) {
508 const struct index_node
*child
;
511 child_count
= node
->last
- node
->first
+ 1;
512 child_offs
= NOFAIL(malloc(child_count
* sizeof(uint32_t)));
514 for (i
= 0; i
< child_count
; i
++) {
515 child
= node
->children
[node
->first
+ i
];
516 child_offs
[i
] = htonl(index_write__node(child
, out
));
520 /* Now write this node */
523 if (node
->prefix
[0]) {
524 fputs(node
->prefix
, out
);
526 offset
|= INDEX_NODE_PREFIX
;
530 fputc(node
->first
, out
);
531 fputc(node
->last
, out
);
532 fwrite(child_offs
, sizeof(uint32_t), child_count
, out
);
534 offset
|= INDEX_NODE_CHILDS
;
538 const struct index_value
*v
;
539 unsigned int value_count
;
543 for (v
= node
->values
; v
!= NULL
; v
= v
->next
)
545 u
= htonl(value_count
);
546 fwrite(&u
, sizeof(u
), 1, out
);
548 for (v
= node
->values
; v
!= NULL
; v
= v
->next
) {
549 u
= htonl(v
->priority
);
550 fwrite(&u
, sizeof(u
), 1, out
);
551 fputs(v
->value
, out
);
554 offset
|= INDEX_NODE_VALUES
;
560 static void index_write(const struct index_node
*node
, FILE *out
)
562 long initial_offset
, final_offset
;
565 u
= htonl(INDEX_MAGIC
);
566 fwrite(&u
, sizeof(u
), 1, out
);
567 u
= htonl(INDEX_VERSION
);
568 fwrite(&u
, sizeof(u
), 1, out
);
570 /* Second word is reserved for the offset of the root node */
571 initial_offset
= ftell(out
);
573 fwrite(&u
, sizeof(uint32_t), 1, out
);
576 u
= htonl(index_write__node(node
, out
));
578 /* Update first word */
579 final_offset
= ftell(out
);
580 fseek(out
, initial_offset
, SEEK_SET
);
581 fwrite(&u
, sizeof(uint32_t), 1, out
);
582 fseek(out
, final_offset
, SEEK_SET
);
585 /* END: code from module-init-tools/index.c just modified to compile here.
588 /* utils (similar to libkmod-utils.c) *********************************/
589 static const char *underscores(const char *input
, char *output
, size_t outputlen
)
593 for (i
= 0; input
[i
] != '\0' && i
< outputlen
- 1; i
++) {
600 WRN("Unmatched bracket in %s\n", input
);
604 size_t off
= strcspn(input
+ i
, "]");
605 if (input
[i
+ off
] == '\0') {
606 WRN("Unmatched bracket in %s\n", input
);
609 memcpy(output
+ i
, input
+ i
, off
+ 1);
615 output
[i
] = input
[i
];
623 static inline char *modname_normalize(const char *modname
, char buf
[NAME_MAX
],
628 for (s
= 0; s
< NAME_MAX
- 1; s
++) {
629 const char c
= modname
[s
];
632 else if (c
== '\0' || c
== '.')
646 static char *path_to_modname(const char *path
, char buf
[NAME_MAX
], size_t *len
)
650 modname
= basename(path
);
651 if (modname
== NULL
|| modname
[0] == '\0')
654 return modname_normalize(modname
, buf
, len
);
657 /* configuration parsing **********************************************/
658 struct cfg_override
{
659 struct cfg_override
*next
;
665 struct cfg_search
*next
;
672 const char *kversion
;
673 char dirname
[PATH_MAX
];
676 uint8_t check_symvers
;
677 uint8_t print_unknown
;
679 struct cfg_override
*overrides
;
680 struct cfg_search
*searches
;
683 static int cfg_search_add(struct cfg
*cfg
, const char *path
, uint8_t builtin
)
685 struct cfg_search
*s
;
691 len
= strlen(path
) + 1;
693 s
= malloc(sizeof(struct cfg_search
) + len
);
695 ERR("search add: out of memory\n");
698 s
->builtin
= builtin
;
703 memcpy(s
->path
, path
, len
);
706 DBG("search add: %s, builtin=%hhu\n", path
, builtin
);
708 s
->next
= cfg
->searches
;
713 static void cfg_search_free(struct cfg_search
*s
)
718 static int cfg_override_add(struct cfg
*cfg
, const char *modname
, const char *subdir
)
720 struct cfg_override
*o
;
721 size_t modnamelen
= strlen(modname
);
722 size_t subdirlen
= strlen(subdir
);
725 o
= malloc(sizeof(struct cfg_override
) + cfg
->dirnamelen
+ 1 +
726 subdirlen
+ 1 + modnamelen
+ 1);
728 ERR("override add: out of memory\n");
731 memcpy(o
->path
, cfg
->dirname
, cfg
->dirnamelen
);
736 memcpy(o
->path
+ i
, subdir
, subdirlen
);
741 memcpy(o
->path
+ i
, modname
, modnamelen
);
743 o
->path
[i
] = '\0'; /* no extension, so we can match .ko/.ko.gz */
747 DBG("override add: %s\n", o
->path
);
749 o
->next
= cfg
->overrides
;
754 static void cfg_override_free(struct cfg_override
*o
)
759 static int cfg_kernel_matches(const struct cfg
*cfg
, const char *pattern
)
765 if (streq(pattern
, "*"))
768 if (regcomp(&re
, pattern
, REG_EXTENDED
|REG_NOSUB
) != 0)
771 status
= regexec(&re
, cfg
->kversion
, 0, NULL
, 0);
777 /* same as libkmod-util.c */
778 static char *getline_wrapped(FILE *fp
, unsigned int *linenum
)
782 char *buf
= malloc(size
);
785 int ch
= getc_unlocked(fp
);
793 /* else fall through */
799 buf
= realloc(buf
, size
+ 1);
804 ch
= getc_unlocked(fp
);
811 /* else fall through */
818 buf
= realloc(buf
, size
);
824 static int cfg_file_parse(struct cfg
*cfg
, const char *filename
)
828 unsigned int linenum
= 0;
831 fp
= fopen(filename
, "r");
834 ERR("file parse %s: %m", filename
);
838 while ((line
= getline_wrapped(fp
, &linenum
)) != NULL
) {
841 if (line
[0] == '\0' || line
[0] == '#')
844 cmd
= strtok_r(line
, "\t ", &saveptr
);
848 if (streq(cmd
, "search")) {
850 while ((sp
= strtok_r(NULL
, "\t ", &saveptr
)) != NULL
) {
851 uint8_t builtin
= streq(sp
, CFG_BUILTIN_KEY
);
852 cfg_search_add(cfg
, sp
, builtin
);
854 } else if (streq(cmd
, "override")) {
855 const char *modname
= strtok_r(NULL
, "\t ", &saveptr
);
856 const char *version
= strtok_r(NULL
, "\t ", &saveptr
);
857 const char *subdir
= strtok_r(NULL
, "\t ", &saveptr
);
859 if (modname
== NULL
|| version
== NULL
||
863 if (!cfg_kernel_matches(cfg
, version
)) {
864 INF("%s:%u: override kernel did not match %s\n",
865 filename
, linenum
, version
);
869 cfg_override_add(cfg
, modname
, subdir
);
870 } else if (streq(cmd
, "include")
871 || streq(cmd
, "make_map_files")) {
872 INF("%s:%u: command %s not implemented yet\n",
873 filename
, linenum
, cmd
);
876 ERR("%s:%u: ignoring bad line starting with '%s'\n",
877 filename
, linenum
, cmd
);
889 static int cfg_files_filter_out(DIR *d
, const char *dir
, const char *name
)
891 size_t len
= strlen(name
);
897 if (len
< 6 || !streq(name
+ len
- 5, ".conf")) {
898 INF("All cfg files need .conf: %s/%s\n", dir
, name
);
902 fstatat(dirfd(d
), name
, &st
, 0);
903 if (S_ISDIR(st
.st_mode
)) {
904 ERR("Directories inside directories are not supported: %s/%s\n",
919 static void cfg_file_free(struct cfg_file
*f
)
924 static int cfg_files_insert_sorted(struct cfg_file
***p_files
, size_t *p_n_files
,
925 const char *dir
, const char *name
)
927 struct cfg_file
**files
, *f
;
928 size_t i
, n_files
, namelen
, dirlen
;
931 dirlen
= strlen(dir
);
933 namelen
= strlen(name
);
935 name
= basename(dir
);
936 namelen
= strlen(name
);
937 dirlen
-= namelen
- 1;
940 n_files
= *p_n_files
;
942 for (i
= 0; i
< n_files
; i
++) {
943 int cmp
= strcmp(name
, files
[i
]->name
);
945 DBG("Ignoring duplicate config file: %.*s/%s\n",
946 (int)dirlen
, dir
, name
);
952 f
= malloc(sizeof(struct cfg_file
) + dirlen
+ namelen
+ 2);
954 ERR("files insert sorted: out of memory\n");
958 tmp
= realloc(files
, sizeof(struct cfg_file
*) * (n_files
+ 1));
960 ERR("files insert sorted: out of memory\n");
964 *p_files
= files
= tmp
;
967 memmove(files
+ i
+ 1, files
+ i
,
968 sizeof(struct cfg_file
*) * (n_files
- i
));
973 f
->namelen
= namelen
;
974 f
->name
= f
->path
+ dirlen
+ 1;
975 memcpy(f
->path
, dir
, dirlen
);
976 f
->path
[dirlen
] = '/';
977 memcpy(f
->path
+ dirlen
+ 1, name
, namelen
);
978 f
->path
[dirlen
+ 1 + namelen
] = '\0';
980 *p_n_files
= n_files
+ 1;
985 * Insert configuration files ignoring duplicates
987 static int cfg_files_list(struct cfg_file
***p_files
, size_t *p_n_files
,
994 if (stat(path
, &st
) != 0) {
996 DBG("could not stat '%s': %m\n", path
);
1000 if (S_ISREG(st
.st_mode
)) {
1001 cfg_files_insert_sorted(p_files
, p_n_files
, path
, NULL
);
1003 } if (!S_ISDIR(st
.st_mode
)) {
1004 ERR("unsupported file mode %s: %#x\n", path
, st
.st_mode
);
1010 ERR("files list %s: %m\n", path
);
1015 struct dirent ent
, *entp
;
1017 err
= readdir_r(d
, &ent
, &entp
);
1019 ERR("reading entry %s\n", strerror(-err
));
1024 if (cfg_files_filter_out(d
, path
, entp
->d_name
))
1027 cfg_files_insert_sorted(p_files
, p_n_files
, path
, entp
->d_name
);
1031 DBG("parsed configuration files from %s: %s\n", path
, strerror(-err
));
1035 static int cfg_load(struct cfg
*cfg
, const char * const *cfg_paths
)
1037 size_t i
, n_files
= 0;
1038 struct cfg_file
**files
= NULL
;
1040 if (cfg_paths
== NULL
)
1041 cfg_paths
= default_cfg_paths
;
1043 for (i
= 0; cfg_paths
[i
] != NULL
; i
++)
1044 cfg_files_list(&files
, &n_files
, cfg_paths
[i
]);
1046 for (i
= 0; i
< n_files
; i
++) {
1047 struct cfg_file
*f
= files
[i
];
1048 cfg_file_parse(cfg
, f
->path
);
1053 /* For backward compatibility add "updates" to the head of the search
1054 * list here. But only if there was no "search" option specified.
1056 if (cfg
->searches
== NULL
)
1057 cfg_search_add(cfg
, "updates", 0);
1062 static void cfg_free(struct cfg
*cfg
)
1064 while (cfg
->overrides
) {
1065 struct cfg_override
*tmp
= cfg
->overrides
;
1066 cfg
->overrides
= cfg
->overrides
->next
;
1067 cfg_override_free(tmp
);
1070 while (cfg
->searches
) {
1071 struct cfg_search
*tmp
= cfg
->searches
;
1072 cfg
->searches
= cfg
->searches
->next
;
1073 cfg_search_free(tmp
);
1078 /* depmod calculations ***********************************************/
1080 struct kmod_module
*kmod
;
1082 const char *relpath
; /* path relative to '$ROOT/lib/modules/$VER/' */
1083 struct array deps
; /* struct symbol */
1084 size_t baselen
; /* points to start of basename/filename */
1086 int sort_idx
; /* sort index using modules.order */
1087 int dep_sort_idx
; /* topological sort index */
1088 uint16_t idx
; /* index in depmod->modules.array */
1089 uint16_t users
; /* how many modules depend on this one */
1090 uint8_t dep_loop
: 1;
1101 const struct cfg
*cfg
;
1102 struct kmod_ctx
*ctx
;
1103 struct array modules
;
1104 struct hash
*modules_by_relpath
;
1105 struct hash
*modules_by_name
;
1106 struct hash
*symbols
;
1107 unsigned int dep_loops
;
1110 static void mod_free(struct mod
*mod
)
1112 DBG("free %p kmod=%p, path=%s\n", mod
, mod
->kmod
, mod
->path
);
1113 array_free_array(&mod
->deps
);
1114 kmod_module_unref(mod
->kmod
);
1118 static int mod_add_dependency(struct mod
*mod
, struct symbol
*sym
)
1122 DBG("%s depends on %s %s\n", mod
->path
, sym
->name
,
1123 sym
->owner
!= NULL
? sym
->owner
->path
: "(unknown)");
1125 if (sym
->owner
== NULL
)
1128 err
= array_append_unique(&mod
->deps
, sym
->owner
);
1134 sym
->owner
->users
++;
1135 SHOW("%s needs \"%s\": %s\n", mod
->path
, sym
->name
, sym
->owner
->path
);
1139 static void symbol_free(struct symbol
*sym
)
1141 DBG("free %p sym=%s, owner=%p %s\n", sym
, sym
->name
, sym
->owner
,
1142 sym
->owner
!= NULL
? sym
->owner
->path
: "");
1146 static int depmod_init(struct depmod
*depmod
, struct cfg
*cfg
, struct kmod_ctx
*ctx
)
1153 array_init(&depmod
->modules
, 128);
1155 depmod
->modules_by_relpath
= hash_new(512, NULL
);
1156 if (depmod
->modules_by_relpath
== NULL
) {
1158 goto modules_by_relpath_failed
;
1161 depmod
->modules_by_name
= hash_new(512, NULL
);
1162 if (depmod
->modules_by_name
== NULL
) {
1164 goto modules_by_name_failed
;
1167 depmod
->symbols
= hash_new(2048, (void (*)(void *))symbol_free
);
1168 if (depmod
->symbols
== NULL
) {
1170 goto symbols_failed
;
1176 hash_free(depmod
->modules_by_name
);
1177 modules_by_name_failed
:
1178 hash_free(depmod
->modules_by_relpath
);
1179 modules_by_relpath_failed
:
1183 static void depmod_shutdown(struct depmod
*depmod
)
1187 hash_free(depmod
->symbols
);
1189 hash_free(depmod
->modules_by_relpath
);
1191 hash_free(depmod
->modules_by_name
);
1193 for (i
= 0; i
< depmod
->modules
.count
; i
++)
1194 mod_free(depmod
->modules
.array
[i
]);
1195 array_free_array(&depmod
->modules
);
1197 kmod_unref(depmod
->ctx
);
1200 static int depmod_module_add(struct depmod
*depmod
, struct kmod_module
*kmod
)
1202 const struct cfg
*cfg
= depmod
->cfg
;
1203 const char *modname
;
1208 modname
= kmod_module_get_name(kmod
);
1209 modnamelen
= strlen(modname
) + 1;
1211 mod
= calloc(1, sizeof(struct mod
) + modnamelen
);
1215 mod
->sort_idx
= depmod
->modules
.count
+ 1;
1216 mod
->dep_sort_idx
= INT32_MAX
;
1217 mod
->idx
= depmod
->modules
.count
;
1218 memcpy(mod
->modname
, modname
, modnamelen
);
1219 mod
->modnamelen
= modnamelen
;
1221 array_init(&mod
->deps
, 4);
1223 mod
->path
= kmod_module_get_path(kmod
);
1224 mod
->baselen
= strrchr(mod
->path
, '/') - mod
->path
+ 1;
1225 if (strncmp(mod
->path
, cfg
->dirname
, cfg
->dirnamelen
) == 0 &&
1226 mod
->path
[cfg
->dirnamelen
] == '/')
1227 mod
->relpath
= mod
->path
+ cfg
->dirnamelen
+ 1;
1229 mod
->relpath
= NULL
;
1231 err
= array_append(&depmod
->modules
, mod
);
1237 err
= hash_add_unique(depmod
->modules_by_name
, mod
->modname
, mod
);
1239 ERR("hash_add_unique %s: %s\n", mod
->modname
, strerror(-err
));
1240 array_pop(&depmod
->modules
);
1245 if (mod
->relpath
!= NULL
) {
1246 err
= hash_add_unique(depmod
->modules_by_relpath
,
1249 ERR("hash_add_unique %s: %s\n",
1250 mod
->relpath
, strerror(-err
));
1251 hash_del(depmod
->modules_by_name
, mod
->modname
);
1252 array_pop(&depmod
->modules
);
1258 DBG("add %p kmod=%p, path=%s\n", mod
, kmod
, mod
->path
);
1263 static int depmod_module_replace(struct depmod
*depmod
, struct mod
*mod
, struct kmod_module
*kmod
)
1265 const struct cfg
*cfg
= depmod
->cfg
;
1266 const char *path
, *relpath
;
1269 path
= kmod_module_get_path(kmod
);
1270 if (strncmp(path
, cfg
->dirname
, cfg
->dirnamelen
) == 0 &&
1271 path
[cfg
->dirnamelen
] == '/')
1272 relpath
= path
+ cfg
->dirnamelen
+ 1;
1276 if (relpath
!= NULL
) {
1277 err
= hash_add_unique(depmod
->modules_by_relpath
, relpath
, mod
);
1279 ERR("hash_add_unique %s: %s\n",
1280 relpath
, strerror(-err
));
1285 if (mod
->relpath
!= NULL
)
1286 hash_del(depmod
->modules_by_relpath
, mod
->relpath
);
1287 kmod_module_unref(mod
->kmod
);
1288 mod
->relpath
= relpath
;
1294 /* returns if existing module @mod is higher priority than newpath.
1295 * note this is the inverse of module-init-tools is_higher_priority()
1297 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
)
1299 const struct cfg
*cfg
= depmod
->cfg
;
1300 const struct cfg_override
*ov
;
1301 const struct cfg_search
*se
;
1302 size_t newlen
= baselen
+ modnamelen
;
1303 size_t oldlen
= mod
->baselen
+ mod
->modnamelen
;
1304 const char *oldpath
= mod
->path
;
1305 int i
, bprio
= -1, oldprio
= -1, newprio
= -1;
1307 DBG("comparing priorities of %s and %s\n",
1310 for (ov
= cfg
->overrides
; ov
!= NULL
; ov
= ov
->next
) {
1311 DBG("override %s\n", ov
->path
);
1312 if (newlen
== ov
->len
&& memcmp(ov
->path
, newpath
, newlen
) == 0)
1314 if (oldlen
== ov
->len
&& memcmp(ov
->path
, oldpath
, oldlen
) == 0)
1318 for (i
= 0, se
= cfg
->searches
; se
!= NULL
; se
= se
->next
, i
++) {
1319 DBG("search %s\n", se
->builtin
? "built-in" : se
->path
);
1322 else if (newlen
>= se
->len
&&
1323 memcmp(se
->path
, newpath
, se
->len
) == 0)
1325 else if (oldlen
>= se
->len
&&
1326 memcmp(se
->path
, oldpath
, se
->len
) == 0)
1335 DBG("priorities: built-in: %d, old: %d, new: %d\n",
1336 bprio
, newprio
, oldprio
);
1338 return newprio
<= oldprio
;
1341 static int depmod_modules_search_file(struct depmod
*depmod
, size_t baselen
, size_t namelen
, const char *path
)
1343 struct kmod_module
*kmod
;
1345 const char *relpath
, *modname
;
1346 const struct kmod_ext
*eitr
;
1348 uint8_t matches
= 0;
1351 for (eitr
= kmod_exts
; eitr
->ext
!= NULL
; eitr
++) {
1352 if (namelen
<= eitr
->len
)
1354 if (streq(path
+ baselen
+ namelen
- eitr
->len
, eitr
->ext
)) {
1362 relpath
= path
+ depmod
->cfg
->dirnamelen
+ 1;
1363 DBG("try %s\n", relpath
);
1365 err
= kmod_module_new_from_path(depmod
->ctx
, path
, &kmod
);
1367 ERR("Could not create module %s: %s\n",
1368 path
, strerror(-err
));
1372 modname
= kmod_module_get_name(kmod
);
1373 mod
= hash_find(depmod
->modules_by_name
, modname
);
1375 err
= depmod_module_add(depmod
, kmod
);
1377 ERR("Could not add module %s: %s\n",
1378 path
, strerror(-err
));
1379 kmod_module_unref(kmod
);
1385 modnamelen
= strlen(modname
);
1386 if (depmod_module_is_higher_priority(depmod
, mod
, baselen
,
1387 namelen
, modnamelen
, path
)) {
1388 DBG("Ignored lower priority: %s, higher: %s\n",
1390 kmod_module_unref(kmod
);
1394 err
= depmod_module_replace(depmod
, mod
, kmod
);
1396 ERR("Could not replace existing module %s\n", path
);
1397 kmod_module_unref(kmod
);
1404 static int depmod_modules_search_dir(struct depmod
*depmod
, DIR *d
, size_t baselen
, char *path
)
1407 int err
= 0, dfd
= dirfd(d
);
1409 while ((de
= readdir(d
)) != NULL
) {
1410 const char *name
= de
->d_name
;
1414 if (name
[0] == '.' && (name
[1] == '\0' ||
1415 (name
[1] == '.' && name
[2] == '\0')))
1417 if (streq(name
, "build") || streq(name
, "source"))
1419 namelen
= strlen(name
);
1420 if (baselen
+ namelen
+ 2 >= PATH_MAX
) {
1421 path
[baselen
] = '\0';
1422 ERR("path is too long %s%s %zd\n", path
, name
);
1425 memcpy(path
+ baselen
, name
, namelen
+ 1);
1427 if (de
->d_type
== DT_REG
)
1429 else if (de
->d_type
== DT_DIR
)
1433 if (fstatat(dfd
, name
, &st
, 0) < 0) {
1434 ERR("fstatat(%d, %s): %m\n", dfd
, name
);
1436 } else if (S_ISREG(st
.st_mode
))
1438 else if (S_ISDIR(st
.st_mode
))
1441 ERR("unsupported file type %s: %o\n",
1442 path
, st
.st_mode
& S_IFMT
);
1450 if (baselen
+ namelen
+ 2 + NAME_MAX
>= PATH_MAX
) {
1451 ERR("directory path is too long %s\n", path
);
1454 fd
= openat(dfd
, name
, O_RDONLY
);
1456 ERR("openat(%d, %s, O_RDONLY): %m\n",
1460 subdir
= fdopendir(fd
);
1461 if (subdir
== NULL
) {
1462 ERR("fdopendir(%d): %m\n", fd
);
1466 path
[baselen
+ namelen
] = '/';
1467 path
[baselen
+ namelen
+ 1] = '\0';
1468 err
= depmod_modules_search_dir(depmod
, subdir
,
1469 baselen
+ namelen
+ 1,
1473 err
= depmod_modules_search_file(depmod
, baselen
,
1478 path
[baselen
+ namelen
] = '\0';
1479 ERR("failed %s: %s\n", path
, strerror(-err
));
1480 err
= 0; /* ignore errors */
1487 static int depmod_modules_search(struct depmod
*depmod
)
1489 char path
[PATH_MAX
];
1490 DIR *d
= opendir(depmod
->cfg
->dirname
);
1495 ERR("Couldn't open directory %s: %m\n", depmod
->cfg
->dirname
);
1499 baselen
= depmod
->cfg
->dirnamelen
;
1500 memcpy(path
, depmod
->cfg
->dirname
, baselen
);
1501 path
[baselen
] = '/';
1503 path
[baselen
] = '\0';
1505 err
= depmod_modules_search_dir(depmod
, d
, baselen
, path
);
1510 static int mod_cmp(const void *pa
, const void *pb
) {
1511 const struct mod
*a
= *(const struct mod
**)pa
;
1512 const struct mod
*b
= *(const struct mod
**)pb
;
1513 if (a
->dep_loop
== b
->dep_loop
)
1514 return a
->sort_idx
- b
->sort_idx
;
1515 else if (a
->dep_loop
)
1517 else if (b
->dep_loop
)
1519 return a
->sort_idx
- b
->sort_idx
;
1522 static void depmod_modules_sort(struct depmod
*depmod
)
1524 char order_file
[PATH_MAX
], line
[PATH_MAX
];
1526 unsigned idx
= 0, total
= 0;
1528 snprintf(order_file
, sizeof(order_file
), "%s/modules.order",
1529 depmod
->cfg
->dirname
);
1530 fp
= fopen(order_file
, "r");
1532 ERR("could not open %s: %m\n", order_file
);
1536 while (fgets(line
, sizeof(line
), fp
) != NULL
) {
1537 size_t len
= strlen(line
);
1541 if (line
[len
- 1] != '\n') {
1542 ERR("%s:%u corrupted line misses '\\n'\n",
1549 fseek(fp
, 0, SEEK_SET
);
1550 while (fgets(line
, sizeof(line
), fp
) != NULL
) {
1551 size_t len
= strlen(line
);
1557 line
[len
- 1] = '\0';
1559 mod
= hash_find(depmod
->modules_by_relpath
, line
);
1562 mod
->sort_idx
= idx
- total
;
1565 array_sort(&depmod
->modules
, mod_cmp
);
1566 for (idx
= 0; idx
< depmod
->modules
.count
; idx
++) {
1567 struct mod
*m
= depmod
->modules
.array
[idx
];
1575 static int depmod_symbol_add(struct depmod
*depmod
, const char *name
, uint64_t crc
, const struct mod
*owner
)
1581 if (name
[0] == depmod
->cfg
->sym_prefix
)
1584 namelen
= strlen(name
) + 1;
1585 sym
= malloc(sizeof(struct symbol
) + namelen
);
1589 sym
->owner
= (struct mod
*)owner
;
1591 memcpy(sym
->name
, name
, namelen
);
1593 err
= hash_add(depmod
->symbols
, sym
->name
, sym
);
1599 DBG("add %p sym=%s, owner=%p %s\n", sym
, sym
->name
, owner
,
1600 owner
!= NULL
? owner
->path
: "");
1605 static struct symbol
*depmod_symbol_find(const struct depmod
*depmod
, const char *name
)
1607 if (name
[0] == '.') /* PPC64 needs this: .foo == foo */
1609 if (name
[0] == depmod
->cfg
->sym_prefix
)
1611 return hash_find(depmod
->symbols
, name
);
1614 static int depmod_load_symbols(struct depmod
*depmod
)
1616 const struct mod
**itr
, **itr_end
;
1618 DBG("load symbols (%zd modules)\n", depmod
->modules
.count
);
1620 itr
= (const struct mod
**)depmod
->modules
.array
;
1621 itr_end
= itr
+ depmod
->modules
.count
;
1622 for (; itr
< itr_end
; itr
++) {
1623 const struct mod
*mod
= *itr
;
1624 struct kmod_list
*l
, *list
= NULL
;
1625 int err
= kmod_module_get_symbols(mod
->kmod
, &list
);
1627 DBG("ignoring %s: no symbols: %s\n",
1628 mod
->path
, strerror(-err
));
1631 kmod_list_foreach(l
, list
) {
1632 const char *name
= kmod_module_symbol_get_symbol(l
);
1633 uint64_t crc
= kmod_module_symbol_get_crc(l
);
1634 depmod_symbol_add(depmod
, name
, crc
, mod
);
1636 kmod_module_symbols_free_list(list
);
1639 DBG("loaded symbols (%zd modules, %zd symbols)\n",
1640 depmod
->modules
.count
, hash_get_count(depmod
->symbols
));
1645 static int depmod_load_module_dependencies(struct depmod
*depmod
, struct mod
*mod
)
1647 const struct cfg
*cfg
= depmod
->cfg
;
1648 struct kmod_list
*l
, *list
= NULL
;
1649 int err
= kmod_module_get_dependency_symbols(mod
->kmod
, &list
);
1651 DBG("ignoring %s: no dependency symbols: %s\n",
1652 mod
->path
, strerror(-err
));
1656 DBG("do dependencies of %s\n", mod
->path
);
1657 kmod_list_foreach(l
, list
) {
1658 const char *name
= kmod_module_dependency_symbol_get_symbol(l
);
1659 uint64_t crc
= kmod_module_dependency_symbol_get_crc(l
);
1660 int bindtype
= kmod_module_dependency_symbol_get_bind(l
);
1661 struct symbol
*sym
= depmod_symbol_find(depmod
, name
);
1662 uint8_t is_weak
= bindtype
== KMOD_SYMBOL_WEAK
;
1665 DBG("%s needs (%c) unknown symbol %s\n",
1666 mod
->path
, bindtype
, name
);
1667 if (cfg
->print_unknown
&& !is_weak
)
1668 WRN("%s needs unknown symbol %s\n",
1673 if (cfg
->check_symvers
&& sym
->crc
!= crc
&& !is_weak
) {
1674 DBG("symbol %s (%#"PRIx64
") module %s (%#"PRIx64
")\n",
1675 sym
->name
, sym
->crc
, mod
->path
, crc
);
1676 if (cfg
->print_unknown
)
1677 WRN("%s disagrees about version of symbol %s\n",
1681 mod_add_dependency(mod
, sym
);
1683 kmod_module_dependency_symbols_free_list(list
);
1687 static int depmod_load_dependencies(struct depmod
*depmod
)
1689 struct mod
**itr
, **itr_end
;
1691 DBG("load dependencies (%zd modules, %zd symbols)\n",
1692 depmod
->modules
.count
, hash_get_count(depmod
->symbols
));
1694 itr
= (struct mod
**)depmod
->modules
.array
;
1695 itr_end
= itr
+ depmod
->modules
.count
;
1696 for (; itr
< itr_end
; itr
++) {
1697 struct mod
*mod
= *itr
;
1698 depmod_load_module_dependencies(depmod
, mod
);
1701 DBG("loaded dependencies (%zd modules, %zd symbols)\n",
1702 depmod
->modules
.count
, hash_get_count(depmod
->symbols
));
1707 static int dep_cmp(const void *pa
, const void *pb
)
1709 const struct mod
*a
= *(const struct mod
**)pa
;
1710 const struct mod
*b
= *(const struct mod
**)pb
;
1711 if (a
->dep_loop
== b
->dep_loop
)
1712 return a
->dep_sort_idx
- b
->dep_sort_idx
;
1713 else if (a
->dep_loop
)
1715 else if (b
->dep_loop
)
1717 return a
->dep_sort_idx
- b
->dep_sort_idx
;
1720 static void depmod_sort_dependencies(struct depmod
*depmod
)
1722 struct mod
**itr
, **itr_end
;
1723 itr
= (struct mod
**)depmod
->modules
.array
;
1724 itr_end
= itr
+ depmod
->modules
.count
;
1725 for (; itr
< itr_end
; itr
++) {
1726 struct mod
*m
= *itr
;
1727 if (m
->deps
.count
> 1)
1728 array_sort(&m
->deps
, dep_cmp
);
1732 static int depmod_calculate_dependencies(struct depmod
*depmod
)
1734 const struct mod
**itrm
;
1735 uint16_t *users
, *roots
, *sorted
;
1736 uint16_t i
, n_roots
= 0, n_sorted
= 0, n_mods
= depmod
->modules
.count
;
1738 users
= malloc(sizeof(uint16_t) * n_mods
* 3);
1741 roots
= users
+ n_mods
;
1742 sorted
= roots
+ n_mods
;
1744 DBG("calculate dependencies and ordering (%zd modules)\n", n_mods
);
1746 assert(depmod
->modules
.count
< UINT16_MAX
);
1748 /* populate modules users (how many modules uses it) */
1749 itrm
= (const struct mod
**)depmod
->modules
.array
;
1750 for (i
= 0; i
< n_mods
; i
++, itrm
++) {
1751 const struct mod
*m
= *itrm
;
1752 users
[i
] = m
->users
;
1753 if (users
[i
] == 0) {
1759 /* topological sort (outputs modules without users first) */
1760 while (n_roots
> 0) {
1761 const struct mod
**itr_dst
, **itr_dst_end
;
1763 uint16_t src_idx
= roots
[--n_roots
];
1765 src
= depmod
->modules
.array
[src_idx
];
1766 src
->dep_sort_idx
= n_sorted
;
1767 sorted
[n_sorted
] = src_idx
;
1770 itr_dst
= (const struct mod
**)src
->deps
.array
;
1771 itr_dst_end
= itr_dst
+ src
->deps
.count
;
1772 for (; itr_dst
< itr_dst_end
; itr_dst
++) {
1773 const struct mod
*dst
= *itr_dst
;
1774 uint16_t dst_idx
= dst
->idx
;
1775 assert(users
[dst_idx
] > 0);
1777 if (users
[dst_idx
] == 0) {
1778 roots
[n_roots
] = dst_idx
;
1784 if (n_sorted
< n_mods
) {
1785 WRN("found %hu modules in dependency cycles!\n",
1787 for (i
= 0; i
< n_mods
; i
++) {
1791 m
= depmod
->modules
.array
[i
];
1792 WRN("%s in dependency cycle!\n", m
->path
);
1794 m
->dep_sort_idx
= INT32_MAX
;
1795 depmod
->dep_loops
++;
1799 depmod_sort_dependencies(depmod
);
1801 DBG("calculated dependencies and ordering (%u loops, %zd modules)\n",
1802 depmod
->dep_loops
, n_mods
);
1808 static int depmod_load(struct depmod
*depmod
)
1812 err
= depmod_load_symbols(depmod
);
1816 err
= depmod_load_dependencies(depmod
);
1820 err
= depmod_calculate_dependencies(depmod
);
1827 static size_t mod_count_all_dependencies(const struct mod
*mod
)
1829 size_t i
, count
= 0;
1830 for (i
= 0; i
< mod
->deps
.count
; i
++) {
1831 const struct mod
*d
= mod
->deps
.array
[i
];
1832 count
+= 1 + mod_count_all_dependencies(d
);
1837 static int mod_fill_all_unique_dependencies(const struct mod
*mod
, const struct mod
**deps
, size_t n_deps
, size_t *last
)
1841 for (i
= 0; i
< mod
->deps
.count
; i
++) {
1842 const struct mod
*d
= mod
->deps
.array
[i
];
1846 for (j
= 0; j
< *last
; j
++) {
1856 if (*last
>= n_deps
)
1860 err
= mod_fill_all_unique_dependencies(d
, deps
, n_deps
, last
);
1867 static const struct mod
**mod_get_all_sorted_dependencies(const struct mod
*mod
, size_t *n_deps
)
1869 const struct mod
**deps
;
1872 *n_deps
= mod_count_all_dependencies(mod
);
1876 deps
= malloc(sizeof(struct mod
*) * (*n_deps
));
1880 if (mod_fill_all_unique_dependencies(mod
, deps
, *n_deps
, &last
) < 0) {
1885 qsort(deps
, last
, sizeof(struct mod
*), dep_cmp
);
1890 static inline const char *mod_get_compressed_path(const struct mod
*mod
)
1892 if (mod
->relpath
!= NULL
)
1893 return mod
->relpath
;
1897 static int output_deps(struct depmod
*depmod
, FILE *out
)
1901 for (i
= 0; i
< depmod
->modules
.count
; i
++) {
1902 const struct mod
**deps
, *mod
= depmod
->modules
.array
[i
];
1903 const char *p
= mod_get_compressed_path(mod
);
1906 if (mod
->dep_loop
) {
1907 DBG("Ignored %s due dependency loops\n", p
);
1911 fprintf(out
, "%s:", p
);
1913 if (mod
->deps
.count
== 0)
1916 deps
= mod_get_all_sorted_dependencies(mod
, &n_deps
);
1918 ERR("Could not get all sorted dependencies of %s\n", p
);
1922 for (j
= 0; j
< n_deps
; j
++) {
1923 const struct mod
*d
= deps
[j
];
1925 DBG("Ignored %s (dependency of %s) "
1926 "due dependency loops\n",
1927 mod_get_compressed_path(d
), p
);
1930 fprintf(out
, " %s", mod_get_compressed_path(d
));
1940 static int output_deps_bin(struct depmod
*depmod
, FILE *out
)
1942 struct index_node
*idx
;
1948 idx
= index_create();
1952 for (i
= 0; i
< depmod
->modules
.count
; i
++) {
1953 const struct mod
**deps
, *mod
= depmod
->modules
.array
[i
];
1954 const char *p
= mod_get_compressed_path(mod
);
1956 size_t j
, n_deps
, linepos
, linelen
, slen
;
1959 if (mod
->dep_loop
) {
1960 DBG("Ignored %s due dependency loops\n", p
);
1964 deps
= mod_get_all_sorted_dependencies(mod
, &n_deps
);
1965 if (deps
== NULL
&& n_deps
> 0) {
1966 ERR("Could not get all sorted dependencies of %s\n", p
);
1970 linelen
= strlen(p
) + 1;
1971 for (j
= 0; j
< n_deps
; j
++) {
1972 const struct mod
*d
= deps
[j
];
1974 DBG("Ignored %s (dependency of %s) "
1975 "due dependency loops\n",
1976 mod_get_compressed_path(d
), p
);
1979 linelen
+= 1 + strlen(mod_get_compressed_path(d
));
1982 line
= malloc(linelen
+ 1);
1985 ERR("modules.deps.bin: out of memory\n");
1991 memcpy(line
+ linepos
, p
, slen
);
1993 line
[linepos
] = ':';
1996 for (j
= 0; j
< n_deps
; j
++) {
1997 const struct mod
*d
= deps
[j
];
2001 line
[linepos
] = ' ';
2004 dp
= mod_get_compressed_path(d
);
2006 memcpy(line
+ linepos
, dp
, slen
);
2009 line
[linepos
] = '\0';
2011 duplicate
= index_insert(idx
, mod
->modname
, line
, mod
->idx
);
2012 if (duplicate
&& depmod
->cfg
->warn_dups
)
2013 WRN("duplicate module deps:\n%s\n", line
);
2018 index_write(idx
, out
);
2024 static int output_aliases(struct depmod
*depmod
, FILE *out
)
2028 fputs("# Aliases extracted from modules themselves.\n", out
);
2030 for (i
= 0; i
< depmod
->modules
.count
; i
++) {
2031 const struct mod
*mod
= depmod
->modules
.array
[i
];
2032 struct kmod_list
*l
, *list
= NULL
;
2033 int r
= kmod_module_get_info(mod
->kmod
, &list
);
2034 if (r
< 0 || list
== NULL
)
2036 kmod_list_foreach(l
, list
) {
2037 const char *key
= kmod_module_info_get_key(l
);
2038 const char *value
= kmod_module_info_get_value(l
);
2040 if (!streq(key
, "alias"))
2043 fprintf(out
, "alias %s %s\n",
2044 value
, kmod_module_get_name(mod
->kmod
));
2046 kmod_module_info_free_list(list
);
2052 static int output_aliases_bin(struct depmod
*depmod
, FILE *out
)
2055 struct index_node
*idx
;
2061 idx
= index_create();
2065 for (i
= 0; i
< depmod
->modules
.count
; i
++) {
2066 const struct mod
*mod
= depmod
->modules
.array
[i
];
2067 struct kmod_list
*l
, *list
= NULL
;
2068 int r
= kmod_module_get_info(mod
->kmod
, &list
);
2069 if (r
< 0 || list
== NULL
)
2071 kmod_list_foreach(l
, list
) {
2072 const char *key
= kmod_module_info_get_key(l
);
2073 const char *value
= kmod_module_info_get_value(l
);
2074 const char *modname
, *alias
;
2077 if (!streq(key
, "alias"))
2080 alias
= underscores(value
, buf
, sizeof(buf
));
2084 modname
= kmod_module_get_name(mod
->kmod
);
2085 duplicate
= index_insert(idx
, alias
, modname
,
2087 if (duplicate
&& depmod
->cfg
->warn_dups
)
2088 WRN("duplicate module alias:\n%s %s\n",
2091 kmod_module_info_free_list(list
);
2094 index_write(idx
, out
);
2100 static int output_softdeps(struct depmod
*depmod
, FILE *out
)
2104 fputs("# Soft dependencies extracted from modules themselves.\n", out
);
2105 fputs("# Copy, with a .conf extension, to /etc/modprobe.d to use "
2106 "it with modprobe.\n", out
);
2108 for (i
= 0; i
< depmod
->modules
.count
; i
++) {
2109 const struct mod
*mod
= depmod
->modules
.array
[i
];
2110 struct kmod_list
*l
, *list
= NULL
;
2111 int r
= kmod_module_get_info(mod
->kmod
, &list
);
2112 if (r
< 0 || list
== NULL
)
2114 kmod_list_foreach(l
, list
) {
2115 const char *key
= kmod_module_info_get_key(l
);
2116 const char *value
= kmod_module_info_get_value(l
);
2118 if (!streq(key
, "softdep"))
2121 fprintf(out
, "softdep %s %s\n",
2122 kmod_module_get_name(mod
->kmod
), value
);
2124 kmod_module_info_free_list(list
);
2130 static int output_symbols(struct depmod
*depmod
, FILE *out
)
2132 struct hash_iter iter
;
2133 const struct symbol
*sym
;
2135 fputs("# Aliases for symbols, used by symbol_request().\n", out
);
2137 hash_iter_init(depmod
->symbols
, &iter
);
2139 while (hash_iter_next(&iter
, NULL
, (const void **) &sym
)) {
2140 if (sym
->owner
== NULL
)
2143 fprintf(out
, "alias symbol:%s %s\n",
2144 sym
->name
, sym
->owner
->modname
);
2150 static int output_symbols_bin(struct depmod
*depmod
, FILE *out
)
2152 struct index_node
*idx
;
2154 size_t baselen
= sizeof("symbol:") - 1;
2155 struct hash_iter iter
;
2156 const struct symbol
*sym
;
2161 idx
= index_create();
2165 memcpy(alias
, "symbol:", baselen
);
2166 hash_iter_init(depmod
->symbols
, &iter
);
2168 while (hash_iter_next(&iter
, NULL
, (const void **) &sym
)) {
2171 if (sym
->owner
== NULL
)
2174 strcpy(alias
+ baselen
, sym
->name
);
2175 duplicate
= index_insert(idx
, alias
, sym
->owner
->modname
,
2178 if (duplicate
&& depmod
->cfg
->warn_dups
)
2179 WRN("duplicate module syms:\n%s %s\n",
2180 alias
, sym
->owner
->modname
);
2183 index_write(idx
, out
);
2189 static int output_builtin_bin(struct depmod
*depmod
, FILE *out
)
2192 struct index_node
*idx
;
2193 char infile
[PATH_MAX
], line
[PATH_MAX
], modname
[NAME_MAX
];
2198 snprintf(infile
, sizeof(infile
), "%s/modules.builtin",
2199 depmod
->cfg
->dirname
);
2200 in
= fopen(infile
, "r");
2203 ERR("Could not open %s: %m\n", infile
);
2207 idx
= index_create();
2213 while (fgets(line
, sizeof(line
), in
) != NULL
) {
2214 if (!isalpha(line
[0])) {
2215 ERR("Invalid modules.builtin line: %s\n", line
);
2219 path_to_modname(line
, modname
, NULL
);
2220 index_insert(idx
, modname
, "", 0);
2223 index_write(idx
, out
);
2230 static int output_devname(struct depmod
*depmod
, FILE *out
)
2234 fputs("# Device nodes to trigger on-demand module loading.\n", out
);
2236 for (i
= 0; i
< depmod
->modules
.count
; i
++) {
2237 const struct mod
*mod
= depmod
->modules
.array
[i
];
2238 struct kmod_list
*l
, *list
= NULL
;
2239 const char *devname
= NULL
;
2241 unsigned int major
= 0, minor
= 0;
2244 r
= kmod_module_get_info(mod
->kmod
, &list
);
2245 if (r
< 0 || list
== NULL
)
2248 kmod_list_foreach(l
, list
) {
2249 const char *key
= kmod_module_info_get_key(l
);
2250 const char *value
= kmod_module_info_get_value(l
);
2251 unsigned int maj
, min
;
2253 if (!streq(key
, "alias"))
2256 if (strstartswith(value
, "devname:"))
2257 devname
= value
+ sizeof("devname:") - 1;
2258 else if (sscanf(value
, "char-major-%u-%u",
2263 } else if (sscanf(value
, "block-major-%u-%u",
2270 if (type
!= '\0' && devname
!= NULL
) {
2271 fprintf(out
, "%s %s %c%u:%u\n",
2272 kmod_module_get_name(mod
->kmod
),
2273 devname
, type
, major
, minor
);
2277 kmod_module_info_free_list(list
);
2283 static int depmod_output(struct depmod
*depmod
, FILE *out
)
2285 static const struct depfile
{
2287 int (*cb
)(struct depmod
*depmod
, FILE *out
);
2288 } *itr
, depfiles
[] = {
2289 {"modules.dep", output_deps
},
2290 {"modules.dep.bin", output_deps_bin
},
2291 {"modules.alias", output_aliases
},
2292 {"modules.alias.bin", output_aliases_bin
},
2293 {"modules.softdep", output_softdeps
},
2294 {"modules.symbols", output_symbols
},
2295 {"modules.symbols.bin", output_symbols_bin
},
2296 {"modules.builtin.bin", output_builtin_bin
},
2297 {"modules.devname", output_devname
},
2300 const char *dname
= depmod
->cfg
->dirname
;
2306 dfd
= open(dname
, O_RDONLY
);
2309 CRIT("Could not open directory %s: %m\n", dname
);
2314 for (itr
= depfiles
; itr
->name
!= NULL
; itr
++) {
2316 char tmp
[NAME_MAX
] = "";
2320 int flags
= O_CREAT
| O_TRUNC
| O_WRONLY
;
2324 snprintf(tmp
, sizeof(tmp
), "%s.tmp", itr
->name
);
2325 fd
= openat(dfd
, tmp
, flags
, mode
);
2327 ERR("openat(%s, %s, %o, %o): %m\n",
2328 dname
, tmp
, flags
, mode
);
2331 fp
= fdopen(fd
, "wb");
2333 ERR("fdopen(%d=%s/%s): %m\n", fd
, dname
, tmp
);
2339 r
= itr
->cb(depmod
, fp
);
2345 if (unlinkat(dfd
, tmp
, 0) != 0)
2346 ERR("unlinkat(%s, %s): %m\n", dname
, tmp
);
2348 unlinkat(dfd
, itr
->name
, 0);
2349 if (renameat(dfd
, tmp
, dfd
, itr
->name
) != 0) {
2351 CRIT("renameat(%s, %s, %s, %s): %m\n",
2352 dname
, tmp
, dname
, itr
->name
);
2363 static void depmod_add_fake_syms(struct depmod
*depmod
)
2365 /* __this_module is magic inserted by kernel loader. */
2366 depmod_symbol_add(depmod
, "__this_module", 0, NULL
);
2367 /* On S390, this is faked up too */
2368 depmod_symbol_add(depmod
, "_GLOBAL_OFFSET_TABLE_", 0, NULL
);
2371 static int depmod_load_symvers(struct depmod
*depmod
, const char *filename
)
2375 unsigned int linenum
= 0;
2378 fp
= fopen(filename
, "r");
2380 DBG("load symvers: %s: %s\n", filename
, strerror(-err
));
2384 /* eg. "0xb352177e\tfind_first_bit\tvmlinux\tEXPORT_SYMBOL" */
2385 while (fgets(line
, sizeof(line
), fp
) != NULL
) {
2386 const char *ver
, *sym
, *where
;
2392 ver
= strtok(line
, " \t");
2393 sym
= strtok(NULL
, " \t");
2394 where
= strtok(NULL
, " \t");
2395 if (!ver
|| !sym
|| !where
)
2398 if (!streq(where
, "vmlinux"))
2401 crc
= strtoull(ver
, &verend
, 16);
2402 if (verend
[0] != '\0') {
2403 ERR("%s:%u Invalid symbol version %s: %m\n",
2404 filename
, linenum
, ver
);
2408 depmod_symbol_add(depmod
, sym
, crc
, NULL
);
2410 depmod_add_fake_syms(depmod
);
2412 DBG("loaded symvers: %s: %s\n", filename
, strerror(-err
));
2418 static int depmod_load_system_map(struct depmod
*depmod
, const char *filename
)
2420 const char ksymstr
[] = "__ksymtab_";
2421 const size_t ksymstr_len
= sizeof(ksymstr
) - 1;
2424 unsigned int linenum
= 0;
2427 fp
= fopen(filename
, "r");
2429 DBG("load System.map: %s: %s\n", filename
, strerror(-err
));
2433 /* eg. c0294200 R __ksymtab_devfs_alloc_devnum */
2434 while (fgets(line
, sizeof(line
), fp
) != NULL
) {
2439 p
= strchr(line
, ' ');
2441 goto invalid_syntax
;
2445 goto invalid_syntax
;
2448 /* Covers gpl-only and normal symbols. */
2449 if (strncmp(p
, ksymstr
, ksymstr_len
) != 0)
2452 end
= strchr(p
, '\n');
2456 depmod_symbol_add(depmod
, p
+ ksymstr_len
, 0, NULL
);
2460 ERR("%s:%u: invalid line: %s\n", filename
, linenum
, line
);
2462 depmod_add_fake_syms(depmod
);
2464 DBG("loaded System.map: %s: %s\n", filename
, strerror(-err
));
2471 static int depfile_up_to_date_dir(DIR *d
, time_t mtime
, size_t baselen
, char *path
)
2474 int err
= 1, dfd
= dirfd(d
);
2476 while ((de
= readdir(d
)) != NULL
) {
2477 const char *name
= de
->d_name
;
2481 if (name
[0] == '.' && (name
[1] == '\0' ||
2482 (name
[1] == '.' && name
[2] == '\0')))
2484 if (streq(name
, "build") || streq(name
, "source"))
2486 namelen
= strlen(name
);
2487 if (baselen
+ namelen
+ 2 >= PATH_MAX
) {
2488 path
[baselen
] = '\0';
2489 ERR("path is too long %s%s %zd\n", path
, name
);
2493 if (fstatat(dfd
, name
, &st
, 0) < 0) {
2494 ERR("fstatat(%d, %s): %m\n", dfd
, name
);
2498 if (S_ISDIR(st
.st_mode
)) {
2501 memcpy(path
+ baselen
, name
, namelen
+ 1);
2502 if (baselen
+ namelen
+ 2 + NAME_MAX
>= PATH_MAX
) {
2503 ERR("directory path is too long %s\n", path
);
2506 fd
= openat(dfd
, name
, O_RDONLY
);
2508 ERR("openat(%d, %s, O_RDONLY): %m\n",
2512 subdir
= fdopendir(fd
);
2513 if (subdir
== NULL
) {
2514 ERR("fdopendir(%d): %m\n", fd
);
2518 path
[baselen
+ namelen
] = '/';
2519 path
[baselen
+ namelen
+ 1] = '\0';
2520 err
= depfile_up_to_date_dir(subdir
, mtime
,
2521 baselen
+ namelen
+ 1,
2524 } else if (S_ISREG(st
.st_mode
)) {
2525 const struct kmod_ext
*eitr
;
2526 uint8_t matches
= 0;
2527 for (eitr
= kmod_exts
; eitr
->ext
!= NULL
; eitr
++) {
2528 if (namelen
<= eitr
->len
)
2530 if (streq(name
+ namelen
- eitr
->len
, eitr
->ext
)) {
2537 memcpy(path
+ baselen
, name
, namelen
+ 1);
2538 err
= st
.st_mtime
<= mtime
;
2540 DBG("%s %"PRIu64
" is newer than %"PRIu64
"\n",
2541 path
, (uint64_t)st
.st_mtime
,
2545 ERR("unsupported file type %s: %o\n",
2546 path
, st
.st_mode
& S_IFMT
);
2551 break; /* outdated! */
2553 path
[baselen
+ namelen
] = '\0';
2554 ERR("failed %s: %s\n", path
, strerror(-err
));
2555 err
= 1; /* ignore errors */
2562 /* uptodate: 1, outdated: 0, errors < 0 */
2563 static int depfile_up_to_date(const char *dirname
)
2565 char path
[PATH_MAX
];
2566 DIR *d
= opendir(dirname
);
2572 ERR("Couldn't open directory %s: %m\n", dirname
);
2576 if (fstatat(dirfd(d
), "modules.dep", &st
, 0) != 0) {
2578 ERR("Couldn't fstatat(%s, modules.dep): %m\n", dirname
);
2583 baselen
= strlen(dirname
);
2584 memcpy(path
, dirname
, baselen
);
2585 path
[baselen
] = '/';
2587 path
[baselen
] = '\0';
2589 err
= depfile_up_to_date_dir(d
, st
.st_mtime
, baselen
, path
);
2594 static int is_version_number(const char *version
)
2596 unsigned int d1
, d2
;
2597 return (sscanf(version
, "%u.%u", &d1
, &d2
) == 2);
2600 static int do_depmod(int argc
, char *argv
[])
2603 int i
, err
= 0, all
= 0, maybe_all
= 0, n_config_paths
= 0;
2604 const char **config_paths
= NULL
;
2605 const char *root
= "";
2606 const char *system_map
= NULL
;
2607 const char *module_symvers
= NULL
;
2608 const char *null_kmod_config
= NULL
;
2610 struct kmod_ctx
*ctx
= NULL
;
2612 struct depmod depmod
;
2614 memset(&cfg
, 0, sizeof(cfg
));
2615 memset(&depmod
, 0, sizeof(depmod
));
2619 c
= getopt_long(argc
, argv
, cmdopts_s
, cmdopts
, &idx
);
2633 size_t bytes
= sizeof(char *) * (n_config_paths
+ 2);
2634 void *tmp
= realloc(config_paths
, bytes
);
2636 fputs("Error: out-of-memory\n", stderr
);
2637 goto cmdline_failed
;
2640 config_paths
[n_config_paths
] = optarg
;
2642 config_paths
[n_config_paths
] = NULL
;
2646 module_symvers
= optarg
;
2647 cfg
.check_symvers
= 1;
2650 system_map
= optarg
;
2653 cfg
.print_unknown
= 1;
2662 if (optarg
[1] != '\0') {
2663 CRIT("-P only takes a single char\n");
2664 goto cmdline_failed
;
2666 cfg
.sym_prefix
= optarg
[0];
2677 "ignored deprecated option --%s\n",
2681 "ignored deprecated option -%c\n", c
);
2687 return EXIT_SUCCESS
;
2689 puts(PACKAGE
" version " VERSION
);
2691 return EXIT_SUCCESS
;
2693 goto cmdline_failed
;
2696 "Error: unexpected getopt_long() value '%c'.\n",
2698 goto cmdline_failed
;
2702 if (optind
< argc
&& is_version_number(argv
[optind
])) {
2703 cfg
.kversion
= argv
[optind
];
2706 if (uname(&un
) < 0) {
2707 CRIT("uname() failed: %s\n", strerror(errno
));
2708 goto cmdline_failed
;
2710 cfg
.kversion
= un
.release
;
2713 cfg
.dirnamelen
= snprintf(cfg
.dirname
, PATH_MAX
,
2714 "%s" ROOTPREFIX
"/lib/modules/%s",
2715 root
, cfg
.kversion
);
2723 /* ignore up-to-date errors (< 0) */
2724 if (depfile_up_to_date(cfg
.dirname
) == 1) {
2725 DBG("%s/modules.dep is up to date!\n", cfg
.dirname
);
2728 DBG("%s/modules.dep is outdated, do -a\n", cfg
.dirname
);
2732 ctx
= kmod_new(cfg
.dirname
, &null_kmod_config
);
2734 CRIT("kmod_new(\"%s\", {NULL}) failed: %m\n", cfg
.dirname
);
2735 goto cmdline_failed
;
2737 kmod_set_log_priority(ctx
, verbose
);
2739 err
= depmod_init(&depmod
, &cfg
, ctx
);
2741 CRIT("depmod_init: %s\n", strerror(-err
));
2742 goto depmod_init_failed
;
2744 ctx
= NULL
; /* owned by depmod */
2746 if (module_symvers
!= NULL
) {
2747 err
= depmod_load_symvers(&depmod
, module_symvers
);
2749 CRIT("Could not load %s: %s\n", module_symvers
,
2751 goto cmdline_failed
;
2753 } else if (system_map
!= NULL
) {
2754 err
= depmod_load_system_map(&depmod
, system_map
);
2756 CRIT("Could not load %s: %s\n", module_symvers
,
2758 goto cmdline_failed
;
2760 } else if (cfg
.print_unknown
) {
2761 WRN("-e needs -E or -F\n");
2762 cfg
.print_unknown
= 0;
2766 err
= cfg_load(&cfg
, config_paths
);
2768 CRIT("Could not load configuration files\n");
2769 goto cmdline_modules_failed
;
2771 err
= depmod_modules_search(&depmod
);
2773 CRIT("Could search modules: %s\n", strerror(-err
));
2774 goto cmdline_modules_failed
;
2777 for (i
= optind
; i
< argc
; i
++) {
2778 const char *path
= argv
[i
];
2779 struct kmod_module
*mod
;
2781 if (path
[0] != '/') {
2782 CRIT("%s: not absolute path.", path
);
2783 goto cmdline_modules_failed
;
2786 err
= kmod_module_new_from_path(depmod
.ctx
, path
, &mod
);
2788 CRIT("Could not create module %s: %s\n",
2789 path
, strerror(-err
));
2790 goto cmdline_modules_failed
;
2793 err
= depmod_module_add(&depmod
, mod
);
2795 CRIT("Could not add module %s: %s\n",
2796 path
, strerror(-err
));
2797 kmod_module_unref(mod
);
2798 goto cmdline_modules_failed
;
2803 depmod_modules_sort(&depmod
);
2804 err
= depmod_load(&depmod
);
2806 goto cmdline_modules_failed
;
2808 err
= depmod_output(&depmod
, out
);
2811 depmod_shutdown(&depmod
);
2814 return err
>= 0 ? EXIT_SUCCESS
: EXIT_FAILURE
;
2816 cmdline_modules_failed
:
2817 depmod_shutdown(&depmod
);
2824 return EXIT_FAILURE
;
2827 #ifndef KMOD_BUNDLE_TOOL
2828 int main(int argc
, char *argv
[])
2830 return do_depmod(argc
, argv
);
2836 const struct kmod_cmd kmod_cmd_compat_depmod
= {
2839 .help
= "compat depmod command",