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"
32 #include <sys/utsname.h>
39 #define DEFAULT_VERBOSE LOG_WARNING
40 static int verbose
= DEFAULT_VERBOSE
;
42 static const struct kmod_ext
{
46 {".ko", sizeof(".ko") - 1},
48 {".ko.gz", sizeof(".ko.gz") - 1},
51 {".ko.xz", sizeof(".ko.xz") - 1},
56 static const char CFG_BUILTIN_KEY
[] = "built-in";
57 static const char *default_cfg_paths
[] = {
59 SYSCONFDIR
"/depmod.d",
60 ROOTPREFIX
"/lib/depmod.d",
64 static const char cmdopts_s
[] = "aAb:C:E:F:euqrvnP:wmVh";
65 static const struct option cmdopts
[] = {
66 {"all", no_argument
, 0, 'a'},
67 {"quick", no_argument
, 0, 'A'},
68 {"basedir", required_argument
, 0, 'b'},
69 {"config", required_argument
, 0, 'C'},
70 {"symvers", required_argument
, 0, 'E'},
71 {"filesyms", required_argument
, 0, 'F'},
72 {"errsyms", no_argument
, 0, 'e'},
73 {"unresolved-error", no_argument
, 0, 'u'}, /* deprecated */
74 {"quiet", no_argument
, 0, 'q'}, /* deprecated */
75 {"root", no_argument
, 0, 'r'}, /* deprecated */
76 {"verbose", no_argument
, 0, 'v'},
77 {"show", no_argument
, 0, 'n'},
78 {"dry-run", no_argument
, 0, 'n'},
79 {"symbol-prefix", no_argument
, 0, 'P'},
80 {"warn", no_argument
, 0, 'w'},
81 {"map", no_argument
, 0, 'm'}, /* deprecated */
82 {"version", no_argument
, 0, 'V'},
83 {"help", no_argument
, 0, 'h'},
87 static void help(const char *progname
)
91 "\t%s -[aA] [options] [forced_version]\n"
93 "If no arguments (except options) are given, \"depmod -a\" is assumed\n"
95 "depmod will output a dependency list suitable for the modprobe utility.\n"
98 "\t-a, --all Probe all modules\n"
99 "\t-A, --quick Only does the work if there's a new module\n"
100 "\t-e, --errsyms Report not supplied symbols\n"
101 "\t-n, --show Write the dependency file on stdout only\n"
102 "\t-P, --symbol-prefix Architecture symbol prefix\n"
103 "\t-C, --config=PATH Read configuration from PATH\n"
104 "\t-v, --verbose Enable verbose mode\n"
105 "\t-w, --warn Warn on duplicates\n"
106 "\t-V, --version show version\n"
107 "\t-h, --help show this help\n"
109 "The following options are useful for people managing distributions:\n"
110 "\t-b, --basedir=DIR Use an image of a module tree.\n"
111 "\t-F, --filesyms=FILE Use the file instead of the\n"
112 "\t current kernel symbols.\n"
113 "\t-E, --symvers=FILE Use Module.symvers file to check\n"
114 "\t symbol versions.\n",
118 static inline void _show(const char *fmt
, ...)
122 if (verbose
<= DEFAULT_VERBOSE
)
126 vfprintf(stdout
, fmt
, args
);
131 static inline void _log(int prio
, const char *fmt
, ...)
133 const char *prioname
;
141 if (vasprintf(&msg
, fmt
, args
) < 0)
155 prioname
= "WARNING";
167 snprintf(buf
, sizeof(buf
), "LOG-%03d", prio
);
171 fprintf(stderr
, "%s: %s", prioname
, msg
);
174 if (prio
<= LOG_CRIT
)
177 #define CRIT(...) _log(LOG_CRIT, __VA_ARGS__)
178 #define ERR(...) _log(LOG_ERR, __VA_ARGS__)
179 #define WRN(...) _log(LOG_WARNING, __VA_ARGS__)
180 #define INF(...) _log(LOG_INFO, __VA_ARGS__)
181 #define DBG(...) _log(LOG_DEBUG, __VA_ARGS__)
182 #define SHOW(...) _show(__VA_ARGS__)
185 /* binary index write *************************************************/
186 #include <arpa/inet.h>
188 /* BEGIN: code from module-init-tools/index.c just modified to compile here.
190 * Original copyright:
191 * index.c: module index file shared functions for modprobe and depmod
192 * Copyright (C) 2008 Alan Jenkins <alan-jenkins@tuffmail.co.uk>.
194 * These programs are free software; you can redistribute it and/or modify
195 * it under the terms of the GNU General Public License as published by
196 * the Free Software Foundation; either version 2 of the License, or
197 * (at your option) any later version.
199 * This program is distributed in the hope that it will be useful,
200 * but WITHOUT ANY WARRANTY; without even the implied warranty of
201 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
202 * GNU General Public License for more details.
204 * You should have received a copy of the GNU General Public License
205 * along with these programs. If not, see <http://www.gnu.org/licenses/>.
208 /* Integers are stored as 32 bit unsigned in "network" order, i.e. MSB first.
209 All files start with a magic number.
211 Magic spells "BOOTFAST". Second one used on newer versioned binary files.
213 /* #define INDEX_MAGIC_OLD 0xB007FA57 */
214 #define INDEX_MAGIC 0xB007F457
216 /* We use a version string to keep track of changes to the binary format
217 * This is stored in the form: INDEX_MAJOR (hi) INDEX_MINOR (lo) just in
218 * case we ever decide to have minor changes that are not incompatible.
221 #define INDEX_VERSION_MAJOR 0x0002
222 #define INDEX_VERSION_MINOR 0x0001
223 #define INDEX_VERSION ((INDEX_VERSION_MAJOR<<16)|INDEX_VERSION_MINOR)
225 /* The index file maps keys to values. Both keys and values are ASCII strings.
226 Each key can have multiple values. Values are sorted by an integer priority.
228 The reader also implements a wildcard search (including range expressions)
229 where the keys in the index are treated as patterns.
230 This feature is required for module aliases.
233 /* Implementation is based on a radix tree, or "trie".
234 Each arc from parent to child is labelled with a character.
235 Each path from the root represents a string.
237 == Example strings ==
247 * Marked node, representing a key and it's values.
258 Naive implementations tend to be very space inefficient; child pointers
259 are stored in arrays indexed by character, but most child pointers are null.
261 Our implementation uses a scheme described by Wikipedia as a Patrica trie,
263 "easiest to understand as a space-optimized trie where
264 each node with only one child is merged with its child"
275 We still use arrays of child pointers indexed by a single character;
276 the remaining characters of the label are stored as a "prefix" in the child.
278 The paper describing the original Patrica trie works on individiual bits -
279 each node has a maximum of two children, which increases space efficiency.
280 However for this application it is simpler to use the ASCII character set.
281 Since the index file is read-only, it can be compressed by omitting null
282 child pointers at the start and end of arrays.
285 #define INDEX_PRIORITY_MIN UINT32_MAX
288 struct index_value
*next
;
289 unsigned int priority
;
293 /* In-memory index (depmod only) */
295 #define INDEX_CHILDMAX 128
297 char *prefix
; /* path compression */
298 struct index_value
*values
;
299 unsigned char first
; /* range of child nodes */
301 struct index_node
*children
[INDEX_CHILDMAX
]; /* indexed by character */
306 uint32_t magic = INDEX_MAGIC;
307 uint32_t version = INDEX_VERSION;
308 uint32_t root_offset;
310 (node_offset & INDEX_NODE_MASK) specifies the file offset of nodes:
312 char[] prefix; // nul terminated
316 uint32_t children[last - first + 1];
318 uint32_t value_count;
321 char[] value; // nul terminated
322 } values[value_count];
324 (node_offset & INDEX_NODE_FLAGS) indicates which fields are present.
325 Empty prefixes are omitted, leaf nodes omit the three child-related fields.
327 This could be optimised further by adding a sparse child format
328 (indicated using a new flag).
331 /* Format of node offsets within index file */
333 INDEX_NODE_FLAGS
= 0xF0000000, /* Flags in high nibble */
334 INDEX_NODE_PREFIX
= 0x80000000,
335 INDEX_NODE_VALUES
= 0x40000000,
336 INDEX_NODE_CHILDS
= 0x20000000,
338 INDEX_NODE_MASK
= 0x0FFFFFFF, /* Offset value */
341 static struct index_node
*index_create(void)
343 struct index_node
*node
;
345 node
= NOFAIL(calloc(sizeof(struct index_node
), 1));
346 node
->prefix
= NOFAIL(strdup(""));
347 node
->first
= INDEX_CHILDMAX
;
352 static void index_values_free(struct index_value
*values
)
355 struct index_value
*value
= values
;
357 values
= value
->next
;
362 static void index_destroy(struct index_node
*node
)
366 for (c
= node
->first
; c
<= node
->last
; c
++) {
367 struct index_node
*child
= node
->children
[c
];
370 index_destroy(child
);
372 index_values_free(node
->values
);
377 static void index__checkstring(const char *str
)
381 for (i
= 0; str
[i
]; i
++) {
384 if (ch
>= INDEX_CHILDMAX
)
385 CRIT("Module index: bad character '%c'=0x%x - only 7-bit ASCII is supported:"
386 "\n%s\n", (char) ch
, (int) ch
, str
);
390 static int index_add_value(struct index_value
**values
,
391 const char *value
, unsigned int priority
)
393 struct index_value
*v
;
397 /* report the presence of duplicate values */
398 for (v
= *values
; v
; v
= v
->next
) {
399 if (streq(v
->value
, value
))
403 /* find position to insert value */
404 while (*values
&& (*values
)->priority
< priority
)
405 values
= &(*values
)->next
;
408 v
= NOFAIL(calloc(sizeof(struct index_value
) + len
+ 1, 1));
410 v
->priority
= priority
;
411 memcpy(v
->value
, value
, len
+ 1);
417 static int index_insert(struct index_node
*node
, const char *key
,
418 const char *value
, unsigned int priority
)
420 int i
= 0; /* index within str */
423 index__checkstring(key
);
424 index__checkstring(value
);
427 int j
; /* index within node->prefix */
429 /* Ensure node->prefix is a prefix of &str[i].
430 If it is not already, then we must split node. */
431 for (j
= 0; node
->prefix
[j
]; j
++) {
432 ch
= node
->prefix
[j
];
434 if (ch
!= key
[i
+j
]) {
435 char *prefix
= node
->prefix
;
436 struct index_node
*n
;
438 /* New child is copy of node with prefix[j+1..N] */
439 n
= NOFAIL(calloc(sizeof(struct index_node
), 1));
440 memcpy(n
, node
, sizeof(struct index_node
));
441 n
->prefix
= NOFAIL(strdup(&prefix
[j
+1]));
443 /* Parent has prefix[0..j], child at prefix[j] */
444 memset(node
, 0, sizeof(struct index_node
));
446 node
->prefix
= prefix
;
449 node
->children
[ch
] = n
;
454 /* j is now length of node->prefix */
459 return index_add_value(&node
->values
, value
, priority
);
461 if (!node
->children
[ch
]) {
462 struct index_node
*child
;
464 if (ch
< node
->first
)
468 node
->children
[ch
] = NOFAIL(calloc(sizeof(struct index_node
), 1));
470 child
= node
->children
[ch
];
471 child
->prefix
= NOFAIL(strdup(&key
[i
+1]));
472 child
->first
= INDEX_CHILDMAX
;
473 index_add_value(&child
->values
, value
, priority
);
478 /* Descend into child node and continue */
479 node
= node
->children
[ch
];
484 static int index__haschildren(const struct index_node
*node
)
486 return node
->first
< INDEX_CHILDMAX
;
489 /* Recursive post-order traversal
491 Pre-order would make for better read-side buffering / readahead / caching.
492 (post-order means you go backwards in the file as you descend the tree).
493 However, index reading is already fast enough.
494 Pre-order is simpler for writing, and depmod is already slow.
496 static uint32_t index_write__node(const struct index_node
*node
, FILE *out
)
498 uint32_t *child_offs
= NULL
;
505 /* Write children and save their offsets */
506 if (index__haschildren(node
)) {
507 const struct index_node
*child
;
510 child_count
= node
->last
- node
->first
+ 1;
511 child_offs
= NOFAIL(malloc(child_count
* sizeof(uint32_t)));
513 for (i
= 0; i
< child_count
; i
++) {
514 child
= node
->children
[node
->first
+ i
];
515 child_offs
[i
] = htonl(index_write__node(child
, out
));
519 /* Now write this node */
522 if (node
->prefix
[0]) {
523 fputs(node
->prefix
, out
);
525 offset
|= INDEX_NODE_PREFIX
;
529 fputc(node
->first
, out
);
530 fputc(node
->last
, out
);
531 fwrite(child_offs
, sizeof(uint32_t), child_count
, out
);
533 offset
|= INDEX_NODE_CHILDS
;
537 const struct index_value
*v
;
538 unsigned int value_count
;
542 for (v
= node
->values
; v
!= NULL
; v
= v
->next
)
544 u
= htonl(value_count
);
545 fwrite(&u
, sizeof(u
), 1, out
);
547 for (v
= node
->values
; v
!= NULL
; v
= v
->next
) {
548 u
= htonl(v
->priority
);
549 fwrite(&u
, sizeof(u
), 1, out
);
550 fputs(v
->value
, out
);
553 offset
|= INDEX_NODE_VALUES
;
559 static void index_write(const struct index_node
*node
, FILE *out
)
561 long initial_offset
, final_offset
;
564 u
= htonl(INDEX_MAGIC
);
565 fwrite(&u
, sizeof(u
), 1, out
);
566 u
= htonl(INDEX_VERSION
);
567 fwrite(&u
, sizeof(u
), 1, out
);
569 /* Second word is reserved for the offset of the root node */
570 initial_offset
= ftell(out
);
572 fwrite(&u
, sizeof(uint32_t), 1, out
);
575 u
= htonl(index_write__node(node
, out
));
577 /* Update first word */
578 final_offset
= ftell(out
);
579 fseek(out
, initial_offset
, SEEK_SET
);
580 fwrite(&u
, sizeof(uint32_t), 1, out
);
581 fseek(out
, final_offset
, SEEK_SET
);
584 /* END: code from module-init-tools/index.c just modified to compile here.
587 /* utils (variants of libkmod-utils.c) *********************************/
588 static const char *underscores2(const char *input
, char *output
, size_t outputlen
)
592 for (i
= 0; input
[i
] != '\0' && i
< outputlen
- 1; i
++) {
599 WRN("Unmatched bracket in %s\n", input
);
603 size_t off
= strcspn(input
+ i
, "]");
604 if (input
[i
+ off
] == '\0') {
605 WRN("Unmatched bracket in %s\n", input
);
608 memcpy(output
+ i
, input
+ i
, off
+ 1);
614 output
[i
] = input
[i
];
622 /* configuration parsing **********************************************/
623 struct cfg_override
{
624 struct cfg_override
*next
;
630 struct cfg_search
*next
;
637 const char *kversion
;
638 char dirname
[PATH_MAX
];
641 uint8_t check_symvers
;
642 uint8_t print_unknown
;
644 struct cfg_override
*overrides
;
645 struct cfg_search
*searches
;
648 static int cfg_search_add(struct cfg
*cfg
, const char *path
, uint8_t builtin
)
650 struct cfg_search
*s
;
656 len
= strlen(path
) + 1;
658 s
= malloc(sizeof(struct cfg_search
) + len
);
660 ERR("search add: out of memory\n");
663 s
->builtin
= builtin
;
668 memcpy(s
->path
, path
, len
);
671 DBG("search add: %s, builtin=%hhu\n", path
, builtin
);
673 s
->next
= cfg
->searches
;
678 static void cfg_search_free(struct cfg_search
*s
)
683 static int cfg_override_add(struct cfg
*cfg
, const char *modname
, const char *subdir
)
685 struct cfg_override
*o
;
686 size_t modnamelen
= strlen(modname
);
687 size_t subdirlen
= strlen(subdir
);
690 o
= malloc(sizeof(struct cfg_override
) + subdirlen
+ 1
693 ERR("override add: out of memory\n");
696 memcpy(o
->path
, subdir
, subdirlen
);
701 memcpy(o
->path
+ i
, modname
, modnamelen
);
703 o
->path
[i
] = '\0'; /* no extension, so we can match .ko/.ko.gz */
707 DBG("override add: %s\n", o
->path
);
709 o
->next
= cfg
->overrides
;
714 static void cfg_override_free(struct cfg_override
*o
)
719 static int cfg_kernel_matches(const struct cfg
*cfg
, const char *pattern
)
725 if (streq(pattern
, "*"))
728 if (regcomp(&re
, pattern
, REG_EXTENDED
|REG_NOSUB
) != 0)
731 status
= regexec(&re
, cfg
->kversion
, 0, NULL
, 0);
737 static int cfg_file_parse(struct cfg
*cfg
, const char *filename
)
741 unsigned int linenum
= 0;
744 fp
= fopen(filename
, "r");
747 ERR("file parse %s: %m\n", filename
);
751 while ((line
= getline_wrapped(fp
, &linenum
)) != NULL
) {
754 if (line
[0] == '\0' || line
[0] == '#')
757 cmd
= strtok_r(line
, "\t ", &saveptr
);
761 if (streq(cmd
, "search")) {
763 while ((sp
= strtok_r(NULL
, "\t ", &saveptr
)) != NULL
) {
764 uint8_t builtin
= streq(sp
, CFG_BUILTIN_KEY
);
765 cfg_search_add(cfg
, sp
, builtin
);
767 } else if (streq(cmd
, "override")) {
768 const char *modname
= strtok_r(NULL
, "\t ", &saveptr
);
769 const char *version
= strtok_r(NULL
, "\t ", &saveptr
);
770 const char *subdir
= strtok_r(NULL
, "\t ", &saveptr
);
772 if (modname
== NULL
|| version
== NULL
||
776 if (!cfg_kernel_matches(cfg
, version
)) {
777 INF("%s:%u: override kernel did not match %s\n",
778 filename
, linenum
, version
);
782 cfg_override_add(cfg
, modname
, subdir
);
783 } else if (streq(cmd
, "include")
784 || streq(cmd
, "make_map_files")) {
785 INF("%s:%u: command %s not implemented yet\n",
786 filename
, linenum
, cmd
);
789 ERR("%s:%u: ignoring bad line starting with '%s'\n",
790 filename
, linenum
, cmd
);
802 static int cfg_files_filter_out(DIR *d
, const char *dir
, const char *name
)
804 size_t len
= strlen(name
);
810 if (len
< 6 || !streq(name
+ len
- 5, ".conf")) {
811 INF("All cfg files need .conf: %s/%s\n", dir
, name
);
815 fstatat(dirfd(d
), name
, &st
, 0);
816 if (S_ISDIR(st
.st_mode
)) {
817 ERR("Directories inside directories are not supported: %s/%s\n",
832 static void cfg_file_free(struct cfg_file
*f
)
837 static int cfg_files_insert_sorted(struct cfg_file
***p_files
, size_t *p_n_files
,
838 const char *dir
, const char *name
)
840 struct cfg_file
**files
, *f
;
841 size_t i
, n_files
, namelen
, dirlen
;
844 dirlen
= strlen(dir
);
846 namelen
= strlen(name
);
848 name
= basename(dir
);
849 namelen
= strlen(name
);
850 dirlen
-= namelen
+ 1;
853 n_files
= *p_n_files
;
855 for (i
= 0; i
< n_files
; i
++) {
856 int cmp
= strcmp(name
, files
[i
]->name
);
858 DBG("Ignoring duplicate config file: %.*s/%s\n",
859 (int)dirlen
, dir
, name
);
865 f
= malloc(sizeof(struct cfg_file
) + dirlen
+ namelen
+ 2);
867 ERR("files insert sorted: out of memory\n");
871 tmp
= realloc(files
, sizeof(struct cfg_file
*) * (n_files
+ 1));
873 ERR("files insert sorted: out of memory\n");
877 *p_files
= files
= tmp
;
880 memmove(files
+ i
+ 1, files
+ i
,
881 sizeof(struct cfg_file
*) * (n_files
- i
));
886 f
->namelen
= namelen
;
887 f
->name
= f
->path
+ dirlen
+ 1;
888 memcpy(f
->path
, dir
, dirlen
);
889 f
->path
[dirlen
] = '/';
890 memcpy(f
->path
+ dirlen
+ 1, name
, namelen
);
891 f
->path
[dirlen
+ 1 + namelen
] = '\0';
893 *p_n_files
= n_files
+ 1;
898 * Insert configuration files ignoring duplicates
900 static int cfg_files_list(struct cfg_file
***p_files
, size_t *p_n_files
,
907 if (stat(path
, &st
) != 0) {
909 DBG("could not stat '%s': %m\n", path
);
913 if (S_ISREG(st
.st_mode
)) {
914 cfg_files_insert_sorted(p_files
, p_n_files
, path
, NULL
);
916 } if (!S_ISDIR(st
.st_mode
)) {
917 ERR("unsupported file mode %s: %#x\n", path
, st
.st_mode
);
923 ERR("files list %s: %m\n", path
);
928 struct dirent ent
, *entp
;
930 err
= readdir_r(d
, &ent
, &entp
);
932 ERR("reading entry %s\n", strerror(-err
));
937 if (cfg_files_filter_out(d
, path
, entp
->d_name
))
940 cfg_files_insert_sorted(p_files
, p_n_files
, path
, entp
->d_name
);
944 DBG("parsed configuration files from %s\n", path
);
948 static int cfg_load(struct cfg
*cfg
, const char * const *cfg_paths
)
950 size_t i
, n_files
= 0;
951 struct cfg_file
**files
= NULL
;
953 if (cfg_paths
== NULL
)
954 cfg_paths
= default_cfg_paths
;
956 for (i
= 0; cfg_paths
[i
] != NULL
; i
++)
957 cfg_files_list(&files
, &n_files
, cfg_paths
[i
]);
959 for (i
= 0; i
< n_files
; i
++) {
960 struct cfg_file
*f
= files
[i
];
961 cfg_file_parse(cfg
, f
->path
);
966 /* For backward compatibility add "updates" to the head of the search
967 * list here. But only if there was no "search" option specified.
969 if (cfg
->searches
== NULL
)
970 cfg_search_add(cfg
, "updates", 0);
975 static void cfg_free(struct cfg
*cfg
)
977 while (cfg
->overrides
) {
978 struct cfg_override
*tmp
= cfg
->overrides
;
979 cfg
->overrides
= cfg
->overrides
->next
;
980 cfg_override_free(tmp
);
983 while (cfg
->searches
) {
984 struct cfg_search
*tmp
= cfg
->searches
;
985 cfg
->searches
= cfg
->searches
->next
;
986 cfg_search_free(tmp
);
991 /* depmod calculations ***********************************************/
993 struct kmod_module
*kmod
;
995 const char *relpath
; /* path relative to '$ROOT/lib/modules/$VER/' */
996 struct array deps
; /* struct symbol */
997 size_t baselen
; /* points to start of basename/filename */
999 int sort_idx
; /* sort index using modules.order */
1000 int dep_sort_idx
; /* topological sort index */
1001 uint16_t idx
; /* index in depmod->modules.array */
1002 uint16_t users
; /* how many modules depend on this one */
1003 uint8_t dep_loop
: 1;
1014 const struct cfg
*cfg
;
1015 struct kmod_ctx
*ctx
;
1016 struct array modules
;
1017 struct hash
*modules_by_relpath
;
1018 struct hash
*modules_by_name
;
1019 struct hash
*symbols
;
1020 unsigned int dep_loops
;
1023 static void mod_free(struct mod
*mod
)
1025 DBG("free %p kmod=%p, path=%s\n", mod
, mod
->kmod
, mod
->path
);
1026 array_free_array(&mod
->deps
);
1027 kmod_module_unref(mod
->kmod
);
1031 static int mod_add_dependency(struct mod
*mod
, struct symbol
*sym
)
1035 DBG("%s depends on %s %s\n", mod
->path
, sym
->name
,
1036 sym
->owner
!= NULL
? sym
->owner
->path
: "(unknown)");
1038 if (sym
->owner
== NULL
)
1041 err
= array_append_unique(&mod
->deps
, sym
->owner
);
1047 sym
->owner
->users
++;
1048 SHOW("%s needs \"%s\": %s\n", mod
->path
, sym
->name
, sym
->owner
->path
);
1052 static void symbol_free(struct symbol
*sym
)
1054 DBG("free %p sym=%s, owner=%p %s\n", sym
, sym
->name
, sym
->owner
,
1055 sym
->owner
!= NULL
? sym
->owner
->path
: "");
1059 static int depmod_init(struct depmod
*depmod
, struct cfg
*cfg
,
1060 struct kmod_ctx
*ctx
)
1067 array_init(&depmod
->modules
, 128);
1069 depmod
->modules_by_relpath
= hash_new(512, NULL
);
1070 if (depmod
->modules_by_relpath
== NULL
) {
1072 goto modules_by_relpath_failed
;
1075 depmod
->modules_by_name
= hash_new(512, NULL
);
1076 if (depmod
->modules_by_name
== NULL
) {
1078 goto modules_by_name_failed
;
1081 depmod
->symbols
= hash_new(2048, (void (*)(void *))symbol_free
);
1082 if (depmod
->symbols
== NULL
) {
1084 goto symbols_failed
;
1090 hash_free(depmod
->modules_by_name
);
1091 modules_by_name_failed
:
1092 hash_free(depmod
->modules_by_relpath
);
1093 modules_by_relpath_failed
:
1097 static void depmod_shutdown(struct depmod
*depmod
)
1101 hash_free(depmod
->symbols
);
1103 hash_free(depmod
->modules_by_relpath
);
1105 hash_free(depmod
->modules_by_name
);
1107 for (i
= 0; i
< depmod
->modules
.count
; i
++)
1108 mod_free(depmod
->modules
.array
[i
]);
1109 array_free_array(&depmod
->modules
);
1111 kmod_unref(depmod
->ctx
);
1114 static int depmod_module_add(struct depmod
*depmod
, struct kmod_module
*kmod
)
1116 const struct cfg
*cfg
= depmod
->cfg
;
1117 const char *modname
;
1122 modname
= kmod_module_get_name(kmod
);
1123 modnamelen
= strlen(modname
) + 1;
1125 mod
= calloc(1, sizeof(struct mod
) + modnamelen
);
1129 mod
->sort_idx
= depmod
->modules
.count
+ 1;
1130 mod
->dep_sort_idx
= INT32_MAX
;
1131 memcpy(mod
->modname
, modname
, modnamelen
);
1132 mod
->modnamelen
= modnamelen
;
1134 array_init(&mod
->deps
, 4);
1136 mod
->path
= kmod_module_get_path(kmod
);
1137 mod
->baselen
= strrchr(mod
->path
, '/') - mod
->path
;
1138 if (strncmp(mod
->path
, cfg
->dirname
, cfg
->dirnamelen
) == 0 &&
1139 mod
->path
[cfg
->dirnamelen
] == '/')
1140 mod
->relpath
= mod
->path
+ cfg
->dirnamelen
+ 1;
1142 mod
->relpath
= NULL
;
1144 err
= hash_add_unique(depmod
->modules_by_name
, mod
->modname
, mod
);
1146 ERR("hash_add_unique %s: %s\n", mod
->modname
, strerror(-err
));
1151 if (mod
->relpath
!= NULL
) {
1152 err
= hash_add_unique(depmod
->modules_by_relpath
,
1155 ERR("hash_add_unique %s: %s\n",
1156 mod
->relpath
, strerror(-err
));
1157 hash_del(depmod
->modules_by_name
, mod
->modname
);
1163 DBG("add %p kmod=%p, path=%s\n", mod
, kmod
, mod
->path
);
1168 static int depmod_module_del(struct depmod
*depmod
, struct mod
*mod
)
1170 DBG("del %p kmod=%p, path=%s\n", mod
, mod
->kmod
, mod
->path
);
1172 if (mod
->relpath
!= NULL
)
1173 hash_del(depmod
->modules_by_relpath
, mod
->relpath
);
1175 hash_del(depmod
->modules_by_name
, mod
->modname
);
1181 /* returns if existing module @mod is higher priority than newpath.
1182 * note this is the inverse of module-init-tools is_higher_priority()
1184 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
)
1186 const struct cfg
*cfg
= depmod
->cfg
;
1187 const struct cfg_override
*ov
;
1188 const struct cfg_search
*se
;
1189 size_t newlen
= baselen
+ modnamelen
;
1190 size_t oldlen
= mod
->baselen
+ mod
->modnamelen
;
1191 const char *oldpath
= mod
->path
;
1192 int i
, bprio
= -1, oldprio
= -1, newprio
= -1;
1194 assert(strncmp(newpath
, cfg
->dirname
, cfg
->dirnamelen
) == 0);
1195 assert(strncmp(oldpath
, cfg
->dirname
, cfg
->dirnamelen
) == 0);
1197 newpath
+= cfg
->dirnamelen
+ 1;
1198 newlen
-= cfg
->dirnamelen
+ 1;
1199 oldpath
+= cfg
->dirnamelen
+ 1;
1200 oldlen
-= cfg
->dirnamelen
+ 1;
1202 DBG("comparing priorities of %s and %s\n",
1205 for (ov
= cfg
->overrides
; ov
!= NULL
; ov
= ov
->next
) {
1206 DBG("override %s\n", ov
->path
);
1207 if (newlen
== ov
->len
&& memcmp(ov
->path
, newpath
, newlen
) == 0)
1209 if (oldlen
== ov
->len
&& memcmp(ov
->path
, oldpath
, oldlen
) == 0)
1213 for (i
= 0, se
= cfg
->searches
; se
!= NULL
; se
= se
->next
, i
++) {
1214 DBG("search %s\n", se
->builtin
? "built-in" : se
->path
);
1217 else if (newlen
>= se
->len
&&
1218 memcmp(se
->path
, newpath
, se
->len
) == 0)
1220 else if (oldlen
>= se
->len
&&
1221 memcmp(se
->path
, oldpath
, se
->len
) == 0)
1230 DBG("priorities: built-in: %d, old: %d, new: %d\n",
1231 bprio
, newprio
, oldprio
);
1233 return newprio
<= oldprio
;
1236 static int depmod_modules_search_file(struct depmod
*depmod
, size_t baselen
, size_t namelen
, const char *path
)
1238 struct kmod_module
*kmod
;
1240 const char *relpath
;
1241 char modname
[PATH_MAX
];
1242 const struct kmod_ext
*eitr
;
1244 uint8_t matches
= 0;
1247 for (eitr
= kmod_exts
; eitr
->ext
!= NULL
; eitr
++) {
1248 if (namelen
<= eitr
->len
)
1250 if (streq(path
+ baselen
+ namelen
- eitr
->len
, eitr
->ext
)) {
1258 if (path_to_modname(path
, modname
, &modnamelen
) == NULL
) {
1259 ERR("could not get modname from path %s\n", path
);
1263 relpath
= path
+ depmod
->cfg
->dirnamelen
+ 1;
1264 DBG("try %s (%s)\n", relpath
, modname
);
1266 mod
= hash_find(depmod
->modules_by_name
, modname
);
1270 if (depmod_module_is_higher_priority(depmod
, mod
, baselen
,
1271 namelen
, modnamelen
, path
)) {
1272 DBG("Ignored lower priority: %s, higher: %s\n",
1277 DBG("Replace lower priority %s with new module %s\n",
1278 mod
->relpath
, relpath
);
1279 err
= depmod_module_del(depmod
, mod
);
1281 ERR("could not del module %s: %s\n", mod
->path
, strerror(-err
));
1286 err
= kmod_module_new_from_path(depmod
->ctx
, path
, &kmod
);
1288 ERR("could not create module %s: %s\n", path
, strerror(-err
));
1292 err
= depmod_module_add(depmod
, kmod
);
1294 ERR("could not add module %s: %s\n",
1295 path
, strerror(-err
));
1296 kmod_module_unref(kmod
);
1302 static int depmod_modules_search_dir(struct depmod
*depmod
, DIR *d
, size_t baselen
, char *path
)
1305 int err
= 0, dfd
= dirfd(d
);
1307 while ((de
= readdir(d
)) != NULL
) {
1308 const char *name
= de
->d_name
;
1312 if (name
[0] == '.' && (name
[1] == '\0' ||
1313 (name
[1] == '.' && name
[2] == '\0')))
1315 if (streq(name
, "build") || streq(name
, "source"))
1317 namelen
= strlen(name
);
1318 if (baselen
+ namelen
+ 2 >= PATH_MAX
) {
1319 path
[baselen
] = '\0';
1320 ERR("path is too long %s%s %zd\n", path
, name
);
1323 memcpy(path
+ baselen
, name
, namelen
+ 1);
1325 if (de
->d_type
== DT_REG
)
1327 else if (de
->d_type
== DT_DIR
)
1331 if (fstatat(dfd
, name
, &st
, 0) < 0) {
1332 ERR("fstatat(%d, %s): %m\n", dfd
, name
);
1334 } else if (S_ISREG(st
.st_mode
))
1336 else if (S_ISDIR(st
.st_mode
))
1339 ERR("unsupported file type %s: %o\n",
1340 path
, st
.st_mode
& S_IFMT
);
1348 if (baselen
+ namelen
+ 2 + NAME_MAX
>= PATH_MAX
) {
1349 ERR("directory path is too long %s\n", path
);
1352 fd
= openat(dfd
, name
, O_RDONLY
);
1354 ERR("openat(%d, %s, O_RDONLY): %m\n",
1358 subdir
= fdopendir(fd
);
1359 if (subdir
== NULL
) {
1360 ERR("fdopendir(%d): %m\n", fd
);
1364 path
[baselen
+ namelen
] = '/';
1365 path
[baselen
+ namelen
+ 1] = '\0';
1366 err
= depmod_modules_search_dir(depmod
, subdir
,
1367 baselen
+ namelen
+ 1,
1371 err
= depmod_modules_search_file(depmod
, baselen
,
1376 path
[baselen
+ namelen
] = '\0';
1377 ERR("failed %s: %s\n", path
, strerror(-err
));
1378 err
= 0; /* ignore errors */
1385 static int depmod_modules_search(struct depmod
*depmod
)
1387 char path
[PATH_MAX
];
1388 DIR *d
= opendir(depmod
->cfg
->dirname
);
1393 ERR("could not open directory %s: %m\n", depmod
->cfg
->dirname
);
1397 baselen
= depmod
->cfg
->dirnamelen
;
1398 memcpy(path
, depmod
->cfg
->dirname
, baselen
);
1399 path
[baselen
] = '/';
1401 path
[baselen
] = '\0';
1403 err
= depmod_modules_search_dir(depmod
, d
, baselen
, path
);
1408 static int mod_cmp(const void *pa
, const void *pb
) {
1409 const struct mod
*a
= *(const struct mod
**)pa
;
1410 const struct mod
*b
= *(const struct mod
**)pb
;
1411 if (a
->dep_loop
== b
->dep_loop
)
1412 return a
->sort_idx
- b
->sort_idx
;
1413 else if (a
->dep_loop
)
1415 else if (b
->dep_loop
)
1417 return a
->sort_idx
- b
->sort_idx
;
1420 static int depmod_modules_build_array(struct depmod
*depmod
)
1422 struct hash_iter module_iter
;
1426 hash_iter_init(depmod
->modules_by_name
, &module_iter
);
1427 while (hash_iter_next(&module_iter
, NULL
, &v
)) {
1428 struct mod
*mod
= (struct mod
*) v
;
1429 mod
->idx
= depmod
->modules
.count
;
1430 err
= array_append(&depmod
->modules
, mod
);
1438 static void depmod_modules_sort(struct depmod
*depmod
)
1440 char order_file
[PATH_MAX
], line
[PATH_MAX
];
1442 unsigned idx
= 0, total
= 0;
1444 snprintf(order_file
, sizeof(order_file
), "%s/modules.order",
1445 depmod
->cfg
->dirname
);
1446 fp
= fopen(order_file
, "r");
1448 WRN("could not open %s: %m\n", order_file
);
1452 while (fgets(line
, sizeof(line
), fp
) != NULL
) {
1453 size_t len
= strlen(line
);
1457 if (line
[len
- 1] != '\n') {
1458 ERR("%s:%u corrupted line misses '\\n'\n",
1465 fseek(fp
, 0, SEEK_SET
);
1466 while (fgets(line
, sizeof(line
), fp
) != NULL
) {
1467 size_t len
= strlen(line
);
1473 line
[len
- 1] = '\0';
1475 mod
= hash_find(depmod
->modules_by_relpath
, line
);
1478 mod
->sort_idx
= idx
- total
;
1481 array_sort(&depmod
->modules
, mod_cmp
);
1482 for (idx
= 0; idx
< depmod
->modules
.count
; idx
++) {
1483 struct mod
*m
= depmod
->modules
.array
[idx
];
1491 static int depmod_symbol_add(struct depmod
*depmod
, const char *name
,
1492 uint64_t crc
, const struct mod
*owner
)
1498 if (name
[0] == depmod
->cfg
->sym_prefix
)
1501 namelen
= strlen(name
) + 1;
1502 sym
= malloc(sizeof(struct symbol
) + namelen
);
1506 sym
->owner
= (struct mod
*)owner
;
1508 memcpy(sym
->name
, name
, namelen
);
1510 err
= hash_add(depmod
->symbols
, sym
->name
, sym
);
1516 DBG("add %p sym=%s, owner=%p %s\n", sym
, sym
->name
, owner
,
1517 owner
!= NULL
? owner
->path
: "");
1522 static struct symbol
*depmod_symbol_find(const struct depmod
*depmod
,
1525 if (name
[0] == '.') /* PPC64 needs this: .foo == foo */
1527 if (name
[0] == depmod
->cfg
->sym_prefix
)
1529 return hash_find(depmod
->symbols
, name
);
1532 static int depmod_load_symbols(struct depmod
*depmod
)
1534 const struct mod
**itr
, **itr_end
;
1536 DBG("load symbols (%zd modules)\n", depmod
->modules
.count
);
1538 itr
= (const struct mod
**)depmod
->modules
.array
;
1539 itr_end
= itr
+ depmod
->modules
.count
;
1540 for (; itr
< itr_end
; itr
++) {
1541 const struct mod
*mod
= *itr
;
1542 struct kmod_list
*l
, *list
= NULL
;
1543 int err
= kmod_module_get_symbols(mod
->kmod
, &list
);
1546 DBG("ignoring %s: no symbols\n", mod
->path
);
1548 ERR("failed to load symbols from %s: %s\n",
1549 mod
->path
, strerror(-err
));
1552 kmod_list_foreach(l
, list
) {
1553 const char *name
= kmod_module_symbol_get_symbol(l
);
1554 uint64_t crc
= kmod_module_symbol_get_crc(l
);
1555 depmod_symbol_add(depmod
, name
, crc
, mod
);
1557 kmod_module_symbols_free_list(list
);
1560 DBG("loaded symbols (%zd modules, %zd symbols)\n",
1561 depmod
->modules
.count
, hash_get_count(depmod
->symbols
));
1566 static int depmod_load_module_dependencies(struct depmod
*depmod
, struct mod
*mod
)
1568 const struct cfg
*cfg
= depmod
->cfg
;
1569 struct kmod_list
*l
, *list
= NULL
;
1570 int err
= kmod_module_get_dependency_symbols(mod
->kmod
, &list
);
1572 DBG("ignoring %s: no dependency symbols: %s\n",
1573 mod
->path
, strerror(-err
));
1577 DBG("do dependencies of %s\n", mod
->path
);
1578 kmod_list_foreach(l
, list
) {
1579 const char *name
= kmod_module_dependency_symbol_get_symbol(l
);
1580 uint64_t crc
= kmod_module_dependency_symbol_get_crc(l
);
1581 int bindtype
= kmod_module_dependency_symbol_get_bind(l
);
1582 struct symbol
*sym
= depmod_symbol_find(depmod
, name
);
1583 uint8_t is_weak
= bindtype
== KMOD_SYMBOL_WEAK
;
1586 DBG("%s needs (%c) unknown symbol %s\n",
1587 mod
->path
, bindtype
, name
);
1588 if (cfg
->print_unknown
&& !is_weak
)
1589 WRN("%s needs unknown symbol %s\n",
1594 if (cfg
->check_symvers
&& sym
->crc
!= crc
&& !is_weak
) {
1595 DBG("symbol %s (%#"PRIx64
") module %s (%#"PRIx64
")\n",
1596 sym
->name
, sym
->crc
, mod
->path
, crc
);
1597 if (cfg
->print_unknown
)
1598 WRN("%s disagrees about version of symbol %s\n",
1602 mod_add_dependency(mod
, sym
);
1604 kmod_module_dependency_symbols_free_list(list
);
1608 static int depmod_load_dependencies(struct depmod
*depmod
)
1610 struct mod
**itr
, **itr_end
;
1612 DBG("load dependencies (%zd modules, %zd symbols)\n",
1613 depmod
->modules
.count
, hash_get_count(depmod
->symbols
));
1615 itr
= (struct mod
**)depmod
->modules
.array
;
1616 itr_end
= itr
+ depmod
->modules
.count
;
1617 for (; itr
< itr_end
; itr
++) {
1618 struct mod
*mod
= *itr
;
1619 depmod_load_module_dependencies(depmod
, mod
);
1622 DBG("loaded dependencies (%zd modules, %zd symbols)\n",
1623 depmod
->modules
.count
, hash_get_count(depmod
->symbols
));
1628 static int dep_cmp(const void *pa
, const void *pb
)
1630 const struct mod
*a
= *(const struct mod
**)pa
;
1631 const struct mod
*b
= *(const struct mod
**)pb
;
1632 if (a
->dep_loop
== b
->dep_loop
)
1633 return a
->dep_sort_idx
- b
->dep_sort_idx
;
1634 else if (a
->dep_loop
)
1636 else if (b
->dep_loop
)
1638 return a
->dep_sort_idx
- b
->dep_sort_idx
;
1641 static void depmod_sort_dependencies(struct depmod
*depmod
)
1643 struct mod
**itr
, **itr_end
;
1644 itr
= (struct mod
**)depmod
->modules
.array
;
1645 itr_end
= itr
+ depmod
->modules
.count
;
1646 for (; itr
< itr_end
; itr
++) {
1647 struct mod
*m
= *itr
;
1648 if (m
->deps
.count
> 1)
1649 array_sort(&m
->deps
, dep_cmp
);
1653 static int depmod_calculate_dependencies(struct depmod
*depmod
)
1655 const struct mod
**itrm
;
1656 uint16_t *users
, *roots
, *sorted
;
1657 uint16_t i
, n_roots
= 0, n_sorted
= 0, n_mods
= depmod
->modules
.count
;
1659 users
= malloc(sizeof(uint16_t) * n_mods
* 3);
1662 roots
= users
+ n_mods
;
1663 sorted
= roots
+ n_mods
;
1665 DBG("calculate dependencies and ordering (%zd modules)\n", n_mods
);
1667 assert(depmod
->modules
.count
< UINT16_MAX
);
1669 /* populate modules users (how many modules uses it) */
1670 itrm
= (const struct mod
**)depmod
->modules
.array
;
1671 for (i
= 0; i
< n_mods
; i
++, itrm
++) {
1672 const struct mod
*m
= *itrm
;
1673 users
[i
] = m
->users
;
1674 if (users
[i
] == 0) {
1680 /* topological sort (outputs modules without users first) */
1681 while (n_roots
> 0) {
1682 const struct mod
**itr_dst
, **itr_dst_end
;
1684 uint16_t src_idx
= roots
[--n_roots
];
1686 src
= depmod
->modules
.array
[src_idx
];
1687 src
->dep_sort_idx
= n_sorted
;
1688 sorted
[n_sorted
] = src_idx
;
1691 itr_dst
= (const struct mod
**)src
->deps
.array
;
1692 itr_dst_end
= itr_dst
+ src
->deps
.count
;
1693 for (; itr_dst
< itr_dst_end
; itr_dst
++) {
1694 const struct mod
*dst
= *itr_dst
;
1695 uint16_t dst_idx
= dst
->idx
;
1696 assert(users
[dst_idx
] > 0);
1698 if (users
[dst_idx
] == 0) {
1699 roots
[n_roots
] = dst_idx
;
1705 if (n_sorted
< n_mods
) {
1706 WRN("found %hu modules in dependency cycles!\n",
1708 for (i
= 0; i
< n_mods
; i
++) {
1712 m
= depmod
->modules
.array
[i
];
1713 WRN("%s in dependency cycle!\n", m
->path
);
1715 m
->dep_sort_idx
= INT32_MAX
;
1716 depmod
->dep_loops
++;
1720 depmod_sort_dependencies(depmod
);
1722 DBG("calculated dependencies and ordering (%u loops, %zd modules)\n",
1723 depmod
->dep_loops
, n_mods
);
1729 static int depmod_load(struct depmod
*depmod
)
1733 err
= depmod_load_symbols(depmod
);
1737 err
= depmod_load_dependencies(depmod
);
1741 err
= depmod_calculate_dependencies(depmod
);
1748 static size_t mod_count_all_dependencies(const struct mod
*mod
)
1750 size_t i
, count
= 0;
1751 for (i
= 0; i
< mod
->deps
.count
; i
++) {
1752 const struct mod
*d
= mod
->deps
.array
[i
];
1753 count
+= 1 + mod_count_all_dependencies(d
);
1758 static int mod_fill_all_unique_dependencies(const struct mod
*mod
, const struct mod
**deps
, size_t n_deps
, size_t *last
)
1762 for (i
= 0; i
< mod
->deps
.count
; i
++) {
1763 const struct mod
*d
= mod
->deps
.array
[i
];
1767 for (j
= 0; j
< *last
; j
++) {
1777 if (*last
>= n_deps
)
1781 err
= mod_fill_all_unique_dependencies(d
, deps
, n_deps
, last
);
1788 static const struct mod
**mod_get_all_sorted_dependencies(const struct mod
*mod
, size_t *n_deps
)
1790 const struct mod
**deps
;
1793 *n_deps
= mod_count_all_dependencies(mod
);
1797 deps
= malloc(sizeof(struct mod
*) * (*n_deps
));
1801 if (mod_fill_all_unique_dependencies(mod
, deps
, *n_deps
, &last
) < 0) {
1806 qsort(deps
, last
, sizeof(struct mod
*), dep_cmp
);
1811 static inline const char *mod_get_compressed_path(const struct mod
*mod
)
1813 if (mod
->relpath
!= NULL
)
1814 return mod
->relpath
;
1818 static int output_deps(struct depmod
*depmod
, FILE *out
)
1822 for (i
= 0; i
< depmod
->modules
.count
; i
++) {
1823 const struct mod
**deps
, *mod
= depmod
->modules
.array
[i
];
1824 const char *p
= mod_get_compressed_path(mod
);
1827 if (mod
->dep_loop
) {
1828 DBG("Ignored %s due dependency loops\n", p
);
1832 fprintf(out
, "%s:", p
);
1834 if (mod
->deps
.count
== 0)
1837 deps
= mod_get_all_sorted_dependencies(mod
, &n_deps
);
1839 ERR("could not get all sorted dependencies of %s\n", p
);
1843 for (j
= 0; j
< n_deps
; j
++) {
1844 const struct mod
*d
= deps
[j
];
1846 DBG("Ignored %s (dependency of %s) "
1847 "due dependency loops\n",
1848 mod_get_compressed_path(d
), p
);
1851 fprintf(out
, " %s", mod_get_compressed_path(d
));
1861 static int output_deps_bin(struct depmod
*depmod
, FILE *out
)
1863 struct index_node
*idx
;
1869 idx
= index_create();
1873 for (i
= 0; i
< depmod
->modules
.count
; i
++) {
1874 const struct mod
**deps
, *mod
= depmod
->modules
.array
[i
];
1875 const char *p
= mod_get_compressed_path(mod
);
1877 size_t j
, n_deps
, linepos
, linelen
, slen
;
1880 if (mod
->dep_loop
) {
1881 DBG("Ignored %s due dependency loops\n", p
);
1885 deps
= mod_get_all_sorted_dependencies(mod
, &n_deps
);
1886 if (deps
== NULL
&& n_deps
> 0) {
1887 ERR("could not get all sorted dependencies of %s\n", p
);
1891 linelen
= strlen(p
) + 1;
1892 for (j
= 0; j
< n_deps
; j
++) {
1893 const struct mod
*d
= deps
[j
];
1895 DBG("Ignored %s (dependency of %s) "
1896 "due dependency loops\n",
1897 mod_get_compressed_path(d
), p
);
1900 linelen
+= 1 + strlen(mod_get_compressed_path(d
));
1903 line
= malloc(linelen
+ 1);
1906 ERR("modules.deps.bin: out of memory\n");
1912 memcpy(line
+ linepos
, p
, slen
);
1914 line
[linepos
] = ':';
1917 for (j
= 0; j
< n_deps
; j
++) {
1918 const struct mod
*d
= deps
[j
];
1922 line
[linepos
] = ' ';
1925 dp
= mod_get_compressed_path(d
);
1927 memcpy(line
+ linepos
, dp
, slen
);
1930 line
[linepos
] = '\0';
1932 duplicate
= index_insert(idx
, mod
->modname
, line
, mod
->idx
);
1933 if (duplicate
&& depmod
->cfg
->warn_dups
)
1934 WRN("duplicate module deps:\n%s\n", line
);
1939 index_write(idx
, out
);
1945 static int output_aliases(struct depmod
*depmod
, FILE *out
)
1949 fputs("# Aliases extracted from modules themselves.\n", out
);
1951 for (i
= 0; i
< depmod
->modules
.count
; i
++) {
1952 const struct mod
*mod
= depmod
->modules
.array
[i
];
1953 struct kmod_list
*l
, *list
= NULL
;
1954 int r
= kmod_module_get_info(mod
->kmod
, &list
);
1955 if (r
< 0 || list
== NULL
)
1957 kmod_list_foreach(l
, list
) {
1958 const char *key
= kmod_module_info_get_key(l
);
1959 const char *value
= kmod_module_info_get_value(l
);
1961 if (!streq(key
, "alias"))
1964 fprintf(out
, "alias %s %s\n",
1965 value
, kmod_module_get_name(mod
->kmod
));
1967 kmod_module_info_free_list(list
);
1973 static int output_aliases_bin(struct depmod
*depmod
, FILE *out
)
1976 struct index_node
*idx
;
1982 idx
= index_create();
1986 for (i
= 0; i
< depmod
->modules
.count
; i
++) {
1987 const struct mod
*mod
= depmod
->modules
.array
[i
];
1988 struct kmod_list
*l
, *list
= NULL
;
1989 int r
= kmod_module_get_info(mod
->kmod
, &list
);
1990 if (r
< 0 || list
== NULL
)
1992 kmod_list_foreach(l
, list
) {
1993 const char *key
= kmod_module_info_get_key(l
);
1994 const char *value
= kmod_module_info_get_value(l
);
1995 const char *modname
, *alias
;
1998 if (!streq(key
, "alias"))
2001 alias
= underscores2(value
, buf
, sizeof(buf
));
2005 modname
= kmod_module_get_name(mod
->kmod
);
2006 duplicate
= index_insert(idx
, alias
, modname
,
2008 if (duplicate
&& depmod
->cfg
->warn_dups
)
2009 WRN("duplicate module alias:\n%s %s\n",
2012 kmod_module_info_free_list(list
);
2015 index_write(idx
, out
);
2021 static int output_softdeps(struct depmod
*depmod
, FILE *out
)
2025 fputs("# Soft dependencies extracted from modules themselves.\n", out
);
2026 fputs("# Copy, with a .conf extension, to /etc/modprobe.d to use "
2027 "it with modprobe.\n", out
);
2029 for (i
= 0; i
< depmod
->modules
.count
; i
++) {
2030 const struct mod
*mod
= depmod
->modules
.array
[i
];
2031 struct kmod_list
*l
, *list
= NULL
;
2032 int r
= kmod_module_get_info(mod
->kmod
, &list
);
2033 if (r
< 0 || list
== NULL
)
2035 kmod_list_foreach(l
, list
) {
2036 const char *key
= kmod_module_info_get_key(l
);
2037 const char *value
= kmod_module_info_get_value(l
);
2039 if (!streq(key
, "softdep"))
2042 fprintf(out
, "softdep %s %s\n",
2043 kmod_module_get_name(mod
->kmod
), value
);
2045 kmod_module_info_free_list(list
);
2051 static int output_symbols(struct depmod
*depmod
, FILE *out
)
2053 struct hash_iter iter
;
2056 fputs("# Aliases for symbols, used by symbol_request().\n", out
);
2058 hash_iter_init(depmod
->symbols
, &iter
);
2060 while (hash_iter_next(&iter
, NULL
, &v
)) {
2061 const struct symbol
*sym
= v
;
2062 if (sym
->owner
== NULL
)
2065 fprintf(out
, "alias symbol:%s %s\n",
2066 sym
->name
, sym
->owner
->modname
);
2072 static int output_symbols_bin(struct depmod
*depmod
, FILE *out
)
2074 struct index_node
*idx
;
2076 size_t baselen
= sizeof("symbol:") - 1;
2077 struct hash_iter iter
;
2083 idx
= index_create();
2087 memcpy(alias
, "symbol:", baselen
);
2088 hash_iter_init(depmod
->symbols
, &iter
);
2090 while (hash_iter_next(&iter
, NULL
, &v
)) {
2092 const struct symbol
*sym
= v
;
2094 if (sym
->owner
== NULL
)
2097 strcpy(alias
+ baselen
, sym
->name
);
2098 duplicate
= index_insert(idx
, alias
, sym
->owner
->modname
,
2101 if (duplicate
&& depmod
->cfg
->warn_dups
)
2102 WRN("duplicate module syms:\n%s %s\n",
2103 alias
, sym
->owner
->modname
);
2106 index_write(idx
, out
);
2112 static int output_builtin_bin(struct depmod
*depmod
, FILE *out
)
2115 struct index_node
*idx
;
2116 char infile
[PATH_MAX
], line
[PATH_MAX
], modname
[PATH_MAX
];
2121 snprintf(infile
, sizeof(infile
), "%s/modules.builtin",
2122 depmod
->cfg
->dirname
);
2123 in
= fopen(infile
, "r");
2126 WRN("could not open %s: %m\n", infile
);
2130 idx
= index_create();
2136 while (fgets(line
, sizeof(line
), in
) != NULL
) {
2137 if (!isalpha(line
[0])) {
2138 ERR("Invalid modules.builtin line: %s\n", line
);
2142 path_to_modname(line
, modname
, NULL
);
2143 index_insert(idx
, modname
, "", 0);
2146 index_write(idx
, out
);
2153 static int output_devname(struct depmod
*depmod
, FILE *out
)
2157 fputs("# Device nodes to trigger on-demand module loading.\n", out
);
2159 for (i
= 0; i
< depmod
->modules
.count
; i
++) {
2160 const struct mod
*mod
= depmod
->modules
.array
[i
];
2161 struct kmod_list
*l
, *list
= NULL
;
2162 const char *devname
= NULL
;
2164 unsigned int major
= 0, minor
= 0;
2167 r
= kmod_module_get_info(mod
->kmod
, &list
);
2168 if (r
< 0 || list
== NULL
)
2171 kmod_list_foreach(l
, list
) {
2172 const char *key
= kmod_module_info_get_key(l
);
2173 const char *value
= kmod_module_info_get_value(l
);
2174 unsigned int maj
, min
;
2176 if (!streq(key
, "alias"))
2179 if (strstartswith(value
, "devname:"))
2180 devname
= value
+ sizeof("devname:") - 1;
2181 else if (sscanf(value
, "char-major-%u-%u",
2186 } else if (sscanf(value
, "block-major-%u-%u",
2193 if (type
!= '\0' && devname
!= NULL
) {
2194 fprintf(out
, "%s %s %c%u:%u\n",
2195 kmod_module_get_name(mod
->kmod
),
2196 devname
, type
, major
, minor
);
2200 kmod_module_info_free_list(list
);
2206 static int depmod_output(struct depmod
*depmod
, FILE *out
)
2208 static const struct depfile
{
2210 int (*cb
)(struct depmod
*depmod
, FILE *out
);
2211 } *itr
, depfiles
[] = {
2212 {"modules.dep", output_deps
},
2213 {"modules.dep.bin", output_deps_bin
},
2214 {"modules.alias", output_aliases
},
2215 {"modules.alias.bin", output_aliases_bin
},
2216 {"modules.softdep", output_softdeps
},
2217 {"modules.symbols", output_symbols
},
2218 {"modules.symbols.bin", output_symbols_bin
},
2219 {"modules.builtin.bin", output_builtin_bin
},
2220 {"modules.devname", output_devname
},
2223 const char *dname
= depmod
->cfg
->dirname
;
2229 dfd
= open(dname
, O_RDONLY
);
2232 CRIT("could not open directory %s: %m\n", dname
);
2237 for (itr
= depfiles
; itr
->name
!= NULL
; itr
++) {
2239 char tmp
[NAME_MAX
] = "";
2243 int flags
= O_CREAT
| O_TRUNC
| O_WRONLY
;
2247 snprintf(tmp
, sizeof(tmp
), "%s.tmp", itr
->name
);
2248 fd
= openat(dfd
, tmp
, flags
, mode
);
2250 ERR("openat(%s, %s, %o, %o): %m\n",
2251 dname
, tmp
, flags
, mode
);
2254 fp
= fdopen(fd
, "wb");
2256 ERR("fdopen(%d=%s/%s): %m\n", fd
, dname
, tmp
);
2262 r
= itr
->cb(depmod
, fp
);
2268 if (unlinkat(dfd
, tmp
, 0) != 0)
2269 ERR("unlinkat(%s, %s): %m\n", dname
, tmp
);
2271 unlinkat(dfd
, itr
->name
, 0);
2272 if (renameat(dfd
, tmp
, dfd
, itr
->name
) != 0) {
2274 CRIT("renameat(%s, %s, %s, %s): %m\n",
2275 dname
, tmp
, dname
, itr
->name
);
2286 static void depmod_add_fake_syms(struct depmod
*depmod
)
2288 /* __this_module is magic inserted by kernel loader. */
2289 depmod_symbol_add(depmod
, "__this_module", 0, NULL
);
2290 /* On S390, this is faked up too */
2291 depmod_symbol_add(depmod
, "_GLOBAL_OFFSET_TABLE_", 0, NULL
);
2294 static int depmod_load_symvers(struct depmod
*depmod
, const char *filename
)
2298 unsigned int linenum
= 0;
2300 fp
= fopen(filename
, "r");
2303 DBG("load symvers: %s: %m\n", filename
);
2306 DBG("load symvers: %s\n", filename
);
2308 /* eg. "0xb352177e\tfind_first_bit\tvmlinux\tEXPORT_SYMBOL" */
2309 while (fgets(line
, sizeof(line
), fp
) != NULL
) {
2310 const char *ver
, *sym
, *where
;
2316 ver
= strtok(line
, " \t");
2317 sym
= strtok(NULL
, " \t");
2318 where
= strtok(NULL
, " \t");
2319 if (!ver
|| !sym
|| !where
)
2322 if (!streq(where
, "vmlinux"))
2325 crc
= strtoull(ver
, &verend
, 16);
2326 if (verend
[0] != '\0') {
2327 ERR("%s:%u Invalid symbol version %s: %m\n",
2328 filename
, linenum
, ver
);
2332 depmod_symbol_add(depmod
, sym
, crc
, NULL
);
2334 depmod_add_fake_syms(depmod
);
2336 DBG("loaded symvers: %s\n", filename
);
2342 static int depmod_load_system_map(struct depmod
*depmod
, const char *filename
)
2344 const char ksymstr
[] = "__ksymtab_";
2345 const size_t ksymstr_len
= sizeof(ksymstr
) - 1;
2348 unsigned int linenum
= 0;
2350 fp
= fopen(filename
, "r");
2353 DBG("load System.map: %s: %m\n", filename
);
2356 DBG("load System.map: %s\n", filename
);
2358 /* eg. c0294200 R __ksymtab_devfs_alloc_devnum */
2359 while (fgets(line
, sizeof(line
), fp
) != NULL
) {
2364 p
= strchr(line
, ' ');
2366 goto invalid_syntax
;
2370 goto invalid_syntax
;
2373 /* Covers gpl-only and normal symbols. */
2374 if (strncmp(p
, ksymstr
, ksymstr_len
) != 0)
2377 end
= strchr(p
, '\n');
2381 depmod_symbol_add(depmod
, p
+ ksymstr_len
, 0, NULL
);
2385 ERR("%s:%u: invalid line: %s\n", filename
, linenum
, line
);
2387 depmod_add_fake_syms(depmod
);
2389 DBG("loaded System.map: %s\n", filename
);
2396 static int depfile_up_to_date_dir(DIR *d
, time_t mtime
, size_t baselen
, char *path
)
2399 int err
= 1, dfd
= dirfd(d
);
2401 while ((de
= readdir(d
)) != NULL
) {
2402 const char *name
= de
->d_name
;
2406 if (name
[0] == '.' && (name
[1] == '\0' ||
2407 (name
[1] == '.' && name
[2] == '\0')))
2409 if (streq(name
, "build") || streq(name
, "source"))
2411 namelen
= strlen(name
);
2412 if (baselen
+ namelen
+ 2 >= PATH_MAX
) {
2413 path
[baselen
] = '\0';
2414 ERR("path is too long %s%s %zd\n", path
, name
);
2418 if (fstatat(dfd
, name
, &st
, 0) < 0) {
2419 ERR("fstatat(%d, %s): %m\n", dfd
, name
);
2423 if (S_ISDIR(st
.st_mode
)) {
2426 memcpy(path
+ baselen
, name
, namelen
+ 1);
2427 if (baselen
+ namelen
+ 2 + NAME_MAX
>= PATH_MAX
) {
2428 ERR("directory path is too long %s\n", path
);
2431 fd
= openat(dfd
, name
, O_RDONLY
);
2433 ERR("openat(%d, %s, O_RDONLY): %m\n",
2437 subdir
= fdopendir(fd
);
2438 if (subdir
== NULL
) {
2439 ERR("fdopendir(%d): %m\n", fd
);
2443 path
[baselen
+ namelen
] = '/';
2444 path
[baselen
+ namelen
+ 1] = '\0';
2445 err
= depfile_up_to_date_dir(subdir
, mtime
,
2446 baselen
+ namelen
+ 1,
2449 } else if (S_ISREG(st
.st_mode
)) {
2450 const struct kmod_ext
*eitr
;
2451 uint8_t matches
= 0;
2452 for (eitr
= kmod_exts
; eitr
->ext
!= NULL
; eitr
++) {
2453 if (namelen
<= eitr
->len
)
2455 if (streq(name
+ namelen
- eitr
->len
, eitr
->ext
)) {
2462 memcpy(path
+ baselen
, name
, namelen
+ 1);
2463 err
= st
.st_mtime
<= mtime
;
2465 DBG("%s %"PRIu64
" is newer than %"PRIu64
"\n",
2466 path
, (uint64_t)st
.st_mtime
,
2470 ERR("unsupported file type %s: %o\n",
2471 path
, st
.st_mode
& S_IFMT
);
2476 break; /* outdated! */
2478 path
[baselen
+ namelen
] = '\0';
2479 ERR("failed %s: %s\n", path
, strerror(-err
));
2480 err
= 1; /* ignore errors */
2487 /* uptodate: 1, outdated: 0, errors < 0 */
2488 static int depfile_up_to_date(const char *dirname
)
2490 char path
[PATH_MAX
];
2491 DIR *d
= opendir(dirname
);
2497 ERR("could not open directory %s: %m\n", dirname
);
2501 if (fstatat(dirfd(d
), "modules.dep", &st
, 0) != 0) {
2503 ERR("could not fstatat(%s, modules.dep): %m\n", dirname
);
2508 baselen
= strlen(dirname
);
2509 memcpy(path
, dirname
, baselen
);
2510 path
[baselen
] = '/';
2512 path
[baselen
] = '\0';
2514 err
= depfile_up_to_date_dir(d
, st
.st_mtime
, baselen
, path
);
2519 static int is_version_number(const char *version
)
2521 unsigned int d1
, d2
;
2522 return (sscanf(version
, "%u.%u", &d1
, &d2
) == 2);
2525 static int do_depmod(int argc
, char *argv
[])
2528 int err
= 0, all
= 0, maybe_all
= 0, n_config_paths
= 0;
2530 const char **config_paths
= NULL
;
2531 const char *system_map
= NULL
;
2532 const char *module_symvers
= NULL
;
2533 const char *null_kmod_config
= NULL
;
2535 struct kmod_ctx
*ctx
= NULL
;
2537 struct depmod depmod
;
2539 memset(&cfg
, 0, sizeof(cfg
));
2540 memset(&depmod
, 0, sizeof(depmod
));
2544 c
= getopt_long(argc
, argv
, cmdopts_s
, cmdopts
, &idx
);
2555 root
= path_make_absolute_cwd(optarg
);
2558 size_t bytes
= sizeof(char *) * (n_config_paths
+ 2);
2559 void *tmp
= realloc(config_paths
, bytes
);
2561 fputs("Error: out-of-memory\n", stderr
);
2562 goto cmdline_failed
;
2565 config_paths
[n_config_paths
] = optarg
;
2567 config_paths
[n_config_paths
] = NULL
;
2571 module_symvers
= optarg
;
2572 cfg
.check_symvers
= 1;
2575 system_map
= optarg
;
2578 cfg
.print_unknown
= 1;
2587 if (optarg
[1] != '\0') {
2588 CRIT("-P only takes a single char\n");
2589 goto cmdline_failed
;
2591 cfg
.sym_prefix
= optarg
[0];
2602 "ignored deprecated option --%s\n",
2606 "ignored deprecated option -%c\n", c
);
2610 help(basename(argv
[0]));
2612 return EXIT_SUCCESS
;
2614 puts(PACKAGE
" version " VERSION
);
2616 return EXIT_SUCCESS
;
2618 goto cmdline_failed
;
2621 "Error: unexpected getopt_long() value '%c'.\n",
2623 goto cmdline_failed
;
2627 if (optind
< argc
&& is_version_number(argv
[optind
])) {
2628 cfg
.kversion
= argv
[optind
];
2631 if (uname(&un
) < 0) {
2632 CRIT("uname() failed: %s\n", strerror(errno
));
2633 goto cmdline_failed
;
2635 cfg
.kversion
= un
.release
;
2638 cfg
.dirnamelen
= snprintf(cfg
.dirname
, PATH_MAX
,
2639 "%s" ROOTPREFIX
"/lib/modules/%s",
2640 root
== NULL
? "" : root
, cfg
.kversion
);
2648 /* ignore up-to-date errors (< 0) */
2649 if (depfile_up_to_date(cfg
.dirname
) == 1) {
2650 DBG("%s/modules.dep is up to date!\n", cfg
.dirname
);
2653 DBG("%s/modules.dep is outdated, do -a\n", cfg
.dirname
);
2657 ctx
= kmod_new(cfg
.dirname
, &null_kmod_config
);
2659 CRIT("kmod_new(\"%s\", {NULL}) failed: %m\n", cfg
.dirname
);
2660 goto cmdline_failed
;
2662 kmod_set_log_priority(ctx
, verbose
);
2664 err
= depmod_init(&depmod
, &cfg
, ctx
);
2666 CRIT("depmod_init: %s\n", strerror(-err
));
2667 goto depmod_init_failed
;
2669 ctx
= NULL
; /* owned by depmod */
2671 if (module_symvers
!= NULL
) {
2672 err
= depmod_load_symvers(&depmod
, module_symvers
);
2674 CRIT("could not load %s: %s\n", module_symvers
,
2676 goto cmdline_failed
;
2678 } else if (system_map
!= NULL
) {
2679 err
= depmod_load_system_map(&depmod
, system_map
);
2681 CRIT("could not load %s: %s\n", system_map
,
2683 goto cmdline_failed
;
2685 } else if (cfg
.print_unknown
) {
2686 WRN("-e needs -E or -F\n");
2687 cfg
.print_unknown
= 0;
2691 err
= cfg_load(&cfg
, config_paths
);
2693 CRIT("could not load configuration files\n");
2694 goto cmdline_modules_failed
;
2696 err
= depmod_modules_search(&depmod
);
2698 CRIT("could not search modules: %s\n", strerror(-err
));
2699 goto cmdline_modules_failed
;
2704 for (i
= optind
; i
< argc
; i
++) {
2705 const char *path
= argv
[i
];
2706 struct kmod_module
*mod
;
2708 if (path
[0] != '/') {
2709 CRIT("%s: not absolute path.\n", path
);
2710 goto cmdline_modules_failed
;
2713 err
= kmod_module_new_from_path(depmod
.ctx
, path
, &mod
);
2715 CRIT("could not create module %s: %s\n",
2716 path
, strerror(-err
));
2717 goto cmdline_modules_failed
;
2720 err
= depmod_module_add(&depmod
, mod
);
2722 CRIT("could not add module %s: %s\n",
2723 path
, strerror(-err
));
2724 kmod_module_unref(mod
);
2725 goto cmdline_modules_failed
;
2730 err
= depmod_modules_build_array(&depmod
);
2732 CRIT("could not build module array: %s\n",
2734 goto cmdline_modules_failed
;
2737 depmod_modules_sort(&depmod
);
2738 err
= depmod_load(&depmod
);
2740 goto cmdline_modules_failed
;
2742 err
= depmod_output(&depmod
, out
);
2745 depmod_shutdown(&depmod
);
2748 return err
>= 0 ? EXIT_SUCCESS
: EXIT_FAILURE
;
2750 cmdline_modules_failed
:
2751 depmod_shutdown(&depmod
);
2759 return EXIT_FAILURE
;
2764 const struct kmod_cmd kmod_cmd_compat_depmod
= {
2767 .help
= "compat depmod command",