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>
36 #define streq(a, b) (strcmp(a, b) == 0)
37 #define strstartswith(a, b) (strncmp(a, b, strlen(b)) == 0)
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-v, --verbose Enable verbose mode\n"
104 "\t-w, --warn Warn on duplicates\n"
105 "\t-V, --version show version\n"
106 "\t-h, --help show this help\n"
108 "The following options are useful for people managing distributions:\n"
109 "\t-b, --basedir=DIR Use an image of a module tree.\n"
110 "\t-F, --filesyms=FILE Use the file instead of the\n"
111 "\t current kernel symbols.\n"
112 "\t-E, --symvers=FILE Use Module.symvers file to check\n"
113 "\t symbol versions.\n",
117 static inline void _show(const char *fmt
, ...)
121 if (verbose
<= DEFAULT_VERBOSE
)
125 vfprintf(stdout
, fmt
, args
);
130 static inline void _log(int prio
, const char *fmt
, ...)
132 const char *prioname
;
140 if (vasprintf(&msg
, fmt
, args
) < 0)
154 prioname
= "WARNING";
166 snprintf(buf
, sizeof(buf
), "LOG-%03d", prio
);
170 fprintf(stderr
, "%s: %s", prioname
, msg
);
173 if (prio
<= LOG_CRIT
)
176 #define CRIT(...) _log(LOG_CRIT, __VA_ARGS__)
177 #define ERR(...) _log(LOG_ERR, __VA_ARGS__)
178 #define WRN(...) _log(LOG_WARNING, __VA_ARGS__)
179 #define INF(...) _log(LOG_INFO, __VA_ARGS__)
180 #define DBG(...) _log(LOG_DEBUG, __VA_ARGS__)
181 #define SHOW(...) _show(__VA_ARGS__)
184 /* binary index write *************************************************/
185 #include <arpa/inet.h>
187 /* BEGIN: code from module-init-tools/index.c just modified to compile here.
189 * Original copyright:
190 * index.c: module index file shared functions for modprobe and depmod
191 * Copyright (C) 2008 Alan Jenkins <alan-jenkins@tuffmail.co.uk>.
193 * These programs are free software; you can redistribute it and/or modify
194 * it under the terms of the GNU General Public License as published by
195 * the Free Software Foundation; either version 2 of the License, or
196 * (at your option) any later version.
198 * This program is distributed in the hope that it will be useful,
199 * but WITHOUT ANY WARRANTY; without even the implied warranty of
200 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
201 * GNU General Public License for more details.
203 * You should have received a copy of the GNU General Public License
204 * along with these programs. If not, see <http://www.gnu.org/licenses/>.
207 /* Integers are stored as 32 bit unsigned in "network" order, i.e. MSB first.
208 All files start with a magic number.
210 Magic spells "BOOTFAST". Second one used on newer versioned binary files.
212 /* #define INDEX_MAGIC_OLD 0xB007FA57 */
213 #define INDEX_MAGIC 0xB007F457
215 /* We use a version string to keep track of changes to the binary format
216 * This is stored in the form: INDEX_MAJOR (hi) INDEX_MINOR (lo) just in
217 * case we ever decide to have minor changes that are not incompatible.
220 #define INDEX_VERSION_MAJOR 0x0002
221 #define INDEX_VERSION_MINOR 0x0001
222 #define INDEX_VERSION ((INDEX_VERSION_MAJOR<<16)|INDEX_VERSION_MINOR)
224 /* The index file maps keys to values. Both keys and values are ASCII strings.
225 Each key can have multiple values. Values are sorted by an integer priority.
227 The reader also implements a wildcard search (including range expressions)
228 where the keys in the index are treated as patterns.
229 This feature is required for module aliases.
232 /* Implementation is based on a radix tree, or "trie".
233 Each arc from parent to child is labelled with a character.
234 Each path from the root represents a string.
236 == Example strings ==
246 * Marked node, representing a key and it's values.
257 Naive implementations tend to be very space inefficient; child pointers
258 are stored in arrays indexed by character, but most child pointers are null.
260 Our implementation uses a scheme described by Wikipedia as a Patrica trie,
262 "easiest to understand as a space-optimized trie where
263 each node with only one child is merged with its child"
274 We still use arrays of child pointers indexed by a single character;
275 the remaining characters of the label are stored as a "prefix" in the child.
277 The paper describing the original Patrica trie works on individiual bits -
278 each node has a maximum of two children, which increases space efficiency.
279 However for this application it is simpler to use the ASCII character set.
280 Since the index file is read-only, it can be compressed by omitting null
281 child pointers at the start and end of arrays.
284 #define INDEX_PRIORITY_MIN UINT32_MAX
287 struct index_value
*next
;
288 unsigned int priority
;
292 /* In-memory index (depmod only) */
294 #define INDEX_CHILDMAX 128
296 char *prefix
; /* path compression */
297 struct index_value
*values
;
298 unsigned char first
; /* range of child nodes */
300 struct index_node
*children
[INDEX_CHILDMAX
]; /* indexed by character */
305 uint32_t magic = INDEX_MAGIC;
306 uint32_t version = INDEX_VERSION;
307 uint32_t root_offset;
309 (node_offset & INDEX_NODE_MASK) specifies the file offset of nodes:
311 char[] prefix; // nul terminated
315 uint32_t children[last - first + 1];
317 uint32_t value_count;
320 char[] value; // nul terminated
321 } values[value_count];
323 (node_offset & INDEX_NODE_FLAGS) indicates which fields are present.
324 Empty prefixes are ommitted, leaf nodes omit the three child-related fields.
326 This could be optimised further by adding a sparse child format
327 (indicated using a new flag).
330 /* Format of node offsets within index file */
332 INDEX_NODE_FLAGS
= 0xF0000000, /* Flags in high nibble */
333 INDEX_NODE_PREFIX
= 0x80000000,
334 INDEX_NODE_VALUES
= 0x40000000,
335 INDEX_NODE_CHILDS
= 0x20000000,
337 INDEX_NODE_MASK
= 0x0FFFFFFF, /* Offset value */
340 static struct index_node
*index_create(void)
342 struct index_node
*node
;
344 node
= NOFAIL(calloc(sizeof(struct index_node
), 1));
345 node
->prefix
= NOFAIL(strdup(""));
346 node
->first
= INDEX_CHILDMAX
;
351 static void index_values_free(struct index_value
*values
)
354 struct index_value
*value
= values
;
356 values
= value
->next
;
361 static void index_destroy(struct index_node
*node
)
365 for (c
= node
->first
; c
<= node
->last
; c
++) {
366 struct index_node
*child
= node
->children
[c
];
369 index_destroy(child
);
371 index_values_free(node
->values
);
376 static void index__checkstring(const char *str
)
380 for (i
= 0; str
[i
]; i
++) {
383 if (ch
>= INDEX_CHILDMAX
)
384 CRIT("Module index: bad character '%c'=0x%x - only 7-bit ASCII is supported:"
385 "\n%s\n", (char) ch
, (int) ch
, str
);
389 static int index_add_value(struct index_value
**values
,
390 const char *value
, unsigned int priority
)
392 struct index_value
*v
;
396 /* report the presence of duplicate values */
397 for (v
= *values
; v
; v
= v
->next
) {
398 if (streq(v
->value
, value
))
402 /* find position to insert value */
403 while (*values
&& (*values
)->priority
< priority
)
404 values
= &(*values
)->next
;
407 v
= NOFAIL(calloc(sizeof(struct index_value
) + len
+ 1, 1));
409 v
->priority
= priority
;
410 memcpy(v
->value
, value
, len
+ 1);
416 static int index_insert(struct index_node
*node
, const char *key
,
417 const char *value
, unsigned int priority
)
419 int i
= 0; /* index within str */
422 index__checkstring(key
);
423 index__checkstring(value
);
426 int j
; /* index within node->prefix */
428 /* Ensure node->prefix is a prefix of &str[i].
429 If it is not already, then we must split node. */
430 for (j
= 0; node
->prefix
[j
]; j
++) {
431 ch
= node
->prefix
[j
];
433 if (ch
!= key
[i
+j
]) {
434 char *prefix
= node
->prefix
;
435 struct index_node
*n
;
437 /* New child is copy of node with prefix[j+1..N] */
438 n
= NOFAIL(calloc(sizeof(struct index_node
), 1));
439 memcpy(n
, node
, sizeof(struct index_node
));
440 n
->prefix
= NOFAIL(strdup(&prefix
[j
+1]));
442 /* Parent has prefix[0..j], child at prefix[j] */
443 memset(node
, 0, sizeof(struct index_node
));
445 node
->prefix
= prefix
;
448 node
->children
[ch
] = n
;
453 /* j is now length of node->prefix */
458 return index_add_value(&node
->values
, value
, priority
);
460 if (!node
->children
[ch
]) {
461 struct index_node
*child
;
463 if (ch
< node
->first
)
467 node
->children
[ch
] = NOFAIL(calloc(sizeof(struct index_node
), 1));
469 child
= node
->children
[ch
];
470 child
->prefix
= NOFAIL(strdup(&key
[i
+1]));
471 child
->first
= INDEX_CHILDMAX
;
472 index_add_value(&child
->values
, value
, priority
);
477 /* Descend into child node and continue */
478 node
= node
->children
[ch
];
483 static int index__haschildren(const struct index_node
*node
)
485 return node
->first
< INDEX_CHILDMAX
;
488 /* Recursive post-order traversal
490 Pre-order would make for better read-side buffering / readahead / caching.
491 (post-order means you go backwards in the file as you descend the tree).
492 However, index reading is already fast enough.
493 Pre-order is simpler for writing, and depmod is already slow.
495 static uint32_t index_write__node(const struct index_node
*node
, FILE *out
)
497 uint32_t *child_offs
= NULL
;
504 /* Write children and save their offsets */
505 if (index__haschildren(node
)) {
506 const struct index_node
*child
;
509 child_count
= node
->last
- node
->first
+ 1;
510 child_offs
= NOFAIL(malloc(child_count
* sizeof(uint32_t)));
512 for (i
= 0; i
< child_count
; i
++) {
513 child
= node
->children
[node
->first
+ i
];
514 child_offs
[i
] = htonl(index_write__node(child
, out
));
518 /* Now write this node */
521 if (node
->prefix
[0]) {
522 fputs(node
->prefix
, out
);
524 offset
|= INDEX_NODE_PREFIX
;
528 fputc(node
->first
, out
);
529 fputc(node
->last
, out
);
530 fwrite(child_offs
, sizeof(uint32_t), child_count
, out
);
532 offset
|= INDEX_NODE_CHILDS
;
536 const struct index_value
*v
;
537 unsigned int value_count
;
541 for (v
= node
->values
; v
!= NULL
; v
= v
->next
)
543 u
= htonl(value_count
);
544 fwrite(&u
, sizeof(u
), 1, out
);
546 for (v
= node
->values
; v
!= NULL
; v
= v
->next
) {
547 u
= htonl(v
->priority
);
548 fwrite(&u
, sizeof(u
), 1, out
);
549 fputs(v
->value
, out
);
552 offset
|= INDEX_NODE_VALUES
;
558 static void index_write(const struct index_node
*node
, FILE *out
)
560 long initial_offset
, final_offset
;
563 u
= htonl(INDEX_MAGIC
);
564 fwrite(&u
, sizeof(u
), 1, out
);
565 u
= htonl(INDEX_VERSION
);
566 fwrite(&u
, sizeof(u
), 1, out
);
568 /* Second word is reserved for the offset of the root node */
569 initial_offset
= ftell(out
);
571 fwrite(&u
, sizeof(uint32_t), 1, out
);
574 u
= htonl(index_write__node(node
, out
));
576 /* Update first word */
577 final_offset
= ftell(out
);
578 fseek(out
, initial_offset
, SEEK_SET
);
579 fwrite(&u
, sizeof(uint32_t), 1, out
);
580 fseek(out
, final_offset
, SEEK_SET
);
583 /* END: code from module-init-tools/index.c just modified to compile here.
587 /* hash like libkmod-hash.c *******************************************/
594 struct hash_entry
*entries
;
602 unsigned int n_buckets
;
603 void (*free_value
)(void *value
);
604 struct hash_bucket buckets
[];
607 static struct hash
*hash_new(unsigned int n_buckets
,
608 void (*free_value
)(void *value
))
610 struct hash
*hash
= calloc(1, sizeof(struct hash
) +
611 n_buckets
* sizeof(struct hash_bucket
));
614 hash
->n_buckets
= n_buckets
;
615 hash
->free_value
= free_value
;
616 hash
->step
= n_buckets
/ 32;
619 else if (hash
->step
> 64)
624 static void hash_free(struct hash
*hash
)
626 struct hash_bucket
*bucket
, *bucket_end
;
627 bucket
= hash
->buckets
;
628 bucket_end
= bucket
+ hash
->n_buckets
;
629 for (; bucket
< bucket_end
; bucket
++) {
630 if (hash
->free_value
) {
631 struct hash_entry
*entry
, *entry_end
;
632 entry
= bucket
->entries
;
633 entry_end
= entry
+ bucket
->used
;
634 for (; entry
< entry_end
; entry
++)
635 hash
->free_value((void *)entry
->value
);
637 free(bucket
->entries
);
642 static inline unsigned int hash_superfast(const char *key
, unsigned int len
)
644 /* Paul Hsieh (http://www.azillionmonkeys.com/qed/hash.html)
645 * used by WebCore (http://webkit.org/blog/8/hashtables-part-2/)
646 * EFL's eina and possible others.
648 unsigned int tmp
, hash
= len
, rem
= len
& 3;
649 const unsigned short *itr
= (const unsigned short *)key
;
654 for (; len
> 0; len
--) {
656 tmp
= (itr
[1] << 11) ^ hash
;
657 hash
= (hash
<< 16) ^ tmp
;
662 /* Handle end cases */
667 hash
^= key
[2] << 18;
678 hash
+= *(const char *)itr
;
683 /* Force "avalanching" of final 127 bits */
695 * add or replace key in hash map.
697 * none of key or value are copied, just references are remembered as is,
698 * make sure they are live while pair exists in hash!
700 static int hash_add(struct hash
*hash
, const char *key
, const void *value
)
702 unsigned int keylen
= strlen(key
);
703 unsigned int hashval
= hash_superfast(key
, keylen
);
704 unsigned int pos
= hashval
% hash
->n_buckets
;
705 struct hash_bucket
*bucket
= hash
->buckets
+ pos
;
706 struct hash_entry
*entry
, *entry_end
;
708 if (bucket
->used
+ 1 >= bucket
->total
) {
709 unsigned new_total
= bucket
->total
+ hash
->step
;
710 size_t size
= new_total
* sizeof(struct hash_entry
);
711 struct hash_entry
*tmp
= realloc(bucket
->entries
, size
);
714 bucket
->entries
= tmp
;
715 bucket
->total
= new_total
;
718 entry
= bucket
->entries
;
719 entry_end
= entry
+ bucket
->used
;
720 for (; entry
< entry_end
; entry
++) {
721 int c
= strcmp(key
, entry
->key
);
723 hash
->free_value((void *)entry
->value
);
724 entry
->value
= value
;
727 memmove(entry
+ 1, entry
,
728 (entry_end
- entry
) * sizeof(struct hash_entry
));
734 entry
->value
= value
;
740 /* similar to hash_add(), but fails if key already exists */
741 static int hash_add_unique(struct hash
*hash
, const char *key
, const void *value
)
743 unsigned int keylen
= strlen(key
);
744 unsigned int hashval
= hash_superfast(key
, keylen
);
745 unsigned int pos
= hashval
% hash
->n_buckets
;
746 struct hash_bucket
*bucket
= hash
->buckets
+ pos
;
747 struct hash_entry
*entry
, *entry_end
;
749 if (bucket
->used
+ 1 >= bucket
->total
) {
750 unsigned new_total
= bucket
->total
+ hash
->step
;
751 size_t size
= new_total
* sizeof(struct hash_entry
);
752 struct hash_entry
*tmp
= realloc(bucket
->entries
, size
);
755 bucket
->entries
= tmp
;
756 bucket
->total
= new_total
;
759 entry
= bucket
->entries
;
760 entry_end
= entry
+ bucket
->used
;
761 for (; entry
< entry_end
; entry
++) {
762 int c
= strcmp(key
, entry
->key
);
766 memmove(entry
+ 1, entry
,
767 (entry_end
- entry
) * sizeof(struct hash_entry
));
773 entry
->value
= value
;
779 static int hash_entry_cmp(const void *pa
, const void *pb
)
781 const struct hash_entry
*a
= pa
;
782 const struct hash_entry
*b
= pb
;
783 return strcmp(a
->key
, b
->key
);
786 static void *hash_find(const struct hash
*hash
, const char *key
)
788 unsigned int keylen
= strlen(key
);
789 unsigned int hashval
= hash_superfast(key
, keylen
);
790 unsigned int pos
= hashval
% hash
->n_buckets
;
791 const struct hash_bucket
*bucket
= hash
->buckets
+ pos
;
792 const struct hash_entry se
= {
796 const struct hash_entry
*entry
= bsearch(
797 &se
, bucket
->entries
, bucket
->used
,
798 sizeof(struct hash_entry
), hash_entry_cmp
);
801 return (void *)entry
->value
;
804 static int hash_del(struct hash
*hash
, const char *key
)
806 unsigned int keylen
= strlen(key
);
807 unsigned int hashval
= hash_superfast(key
, keylen
);
808 unsigned int pos
= hashval
% hash
->n_buckets
;
809 unsigned int steps_used
, steps_total
;
810 struct hash_bucket
*bucket
= hash
->buckets
+ pos
;
811 struct hash_entry
*entry
, *entry_end
;
812 const struct hash_entry se
= {
817 entry
= bsearch(&se
, bucket
->entries
, bucket
->used
,
818 sizeof(struct hash_entry
), hash_entry_cmp
);
822 entry_end
= bucket
->entries
+ bucket
->used
;
823 memmove(entry
, entry
+ 1,
824 (entry_end
- entry
) * sizeof(struct hash_entry
));
829 steps_used
= bucket
->used
/ hash
->step
;
830 steps_total
= bucket
->total
/ hash
->step
;
831 if (steps_used
+ 1 < steps_total
) {
832 size_t size
= (steps_used
+ 1) *
833 hash
->step
* sizeof(struct hash_entry
);
834 struct hash_entry
*tmp
= realloc(bucket
->entries
, size
);
836 bucket
->entries
= tmp
;
837 bucket
->total
= (steps_used
+ 1) * hash
->step
;
844 static unsigned int hash_get_count(const struct hash
*hash
)
849 /* basic pointer array growing in steps ******************************/
857 static void array_init(struct array
*array
, size_t step
)
866 static int array_append(struct array
*array
, const void *element
)
870 if (array
->count
+ 1 >= array
->total
) {
871 size_t new_total
= array
->total
+ array
->step
;
872 void *tmp
= realloc(array
->array
, sizeof(void *) * new_total
);
873 assert(array
->step
> 0);
877 array
->total
= new_total
;
880 array
->array
[idx
] = (void *)element
;
885 static int array_append_unique(struct array
*array
, const void *element
)
887 void **itr
= array
->array
;
888 void **itr_end
= itr
+ array
->count
;
889 for (; itr
< itr_end
; itr
++)
892 return array_append(array
, element
);
895 static void array_pop(struct array
*array
) {
897 if (array
->count
+ array
->step
< array
->total
) {
898 size_t new_total
= array
->total
- array
->step
;
899 void *tmp
= realloc(array
->array
, sizeof(void *) * new_total
);
900 assert(array
->step
> 0);
904 array
->total
= new_total
;
908 static void array_free_array(struct array
*array
) {
915 static void array_sort(struct array
*array
, int (*cmp
)(const void *a
, const void *b
))
917 qsort(array
->array
, array
->count
, sizeof(void *), cmp
);
920 /* utils (similar to libkmod-utils.c) *********************************/
921 static const char *underscores(const char *input
, char *output
, size_t outputlen
)
925 for (i
= 0; input
[i
] != '\0' && i
< outputlen
- 1; i
++) {
932 WRN("Unmatched bracket in %s\n", input
);
936 size_t off
= strcspn(input
+ i
, "]");
937 if (input
[i
+ off
] == '\0') {
938 WRN("Unmatched bracket in %s\n", input
);
941 memcpy(output
+ i
, input
+ i
, off
+ 1);
947 output
[i
] = input
[i
];
955 static inline char *modname_normalize(const char *modname
, char buf
[NAME_MAX
],
960 for (s
= 0; s
< NAME_MAX
- 1; s
++) {
961 const char c
= modname
[s
];
964 else if (c
== '\0' || c
== '.')
978 static char *path_to_modname(const char *path
, char buf
[NAME_MAX
], size_t *len
)
982 modname
= basename(path
);
983 if (modname
== NULL
|| modname
[0] == '\0')
986 return modname_normalize(modname
, buf
, len
);
989 /* configuration parsing **********************************************/
990 struct cfg_override
{
991 struct cfg_override
*next
;
997 struct cfg_search
*next
;
1004 const char *kversion
;
1005 char dirname
[PATH_MAX
];
1008 uint8_t check_symvers
;
1009 uint8_t print_unknown
;
1011 struct cfg_override
*overrides
;
1012 struct cfg_search
*searches
;
1015 static int cfg_search_add(struct cfg
*cfg
, const char *path
, uint8_t builtin
)
1017 struct cfg_search
*s
;
1023 len
= strlen(path
) + 1;
1025 s
= malloc(sizeof(struct cfg_search
) + len
);
1027 ERR("search add: out of memory\n");
1030 s
->builtin
= builtin
;
1035 memcpy(s
->path
, path
, len
);
1038 DBG("search add: %s, builtin=%hhu\n", path
, builtin
);
1040 s
->next
= cfg
->searches
;
1045 static void cfg_search_free(struct cfg_search
*s
)
1050 static int cfg_override_add(struct cfg
*cfg
, const char *modname
, const char *subdir
)
1052 struct cfg_override
*o
;
1053 size_t modnamelen
= strlen(modname
);
1054 size_t subdirlen
= strlen(subdir
);
1057 o
= malloc(sizeof(struct cfg_override
) + cfg
->dirnamelen
+ 1 +
1058 subdirlen
+ 1 + modnamelen
+ 1);
1060 ERR("override add: out of memory\n");
1063 memcpy(o
->path
, cfg
->dirname
, cfg
->dirnamelen
);
1064 i
= cfg
->dirnamelen
;
1068 memcpy(o
->path
+ i
, subdir
, subdirlen
);
1073 memcpy(o
->path
+ i
, modname
, modnamelen
);
1075 o
->path
[i
] = '\0'; /* no extension, so we can match .ko/.ko.gz */
1079 DBG("override add: %s\n", o
->path
);
1081 o
->next
= cfg
->overrides
;
1086 static void cfg_override_free(struct cfg_override
*o
)
1091 static int cfg_kernel_matches(const struct cfg
*cfg
, const char *pattern
)
1097 if (streq(pattern
, "*"))
1100 if (regcomp(&re
, pattern
, REG_EXTENDED
|REG_NOSUB
) != 0)
1103 status
= regexec(&re
, cfg
->kversion
, 0, NULL
, 0);
1109 /* same as libkmod-util.c */
1110 static char *getline_wrapped(FILE *fp
, unsigned int *linenum
)
1114 char *buf
= malloc(size
);
1117 int ch
= getc_unlocked(fp
);
1125 /* else fall through */
1131 buf
= realloc(buf
, size
+ 1);
1136 ch
= getc_unlocked(fp
);
1143 /* else fall through */
1150 buf
= realloc(buf
, size
);
1156 static int cfg_file_parse(struct cfg
*cfg
, const char *filename
)
1160 unsigned int linenum
= 0;
1163 fp
= fopen(filename
, "r");
1166 ERR("file parse %s: %m", filename
);
1170 while ((line
= getline_wrapped(fp
, &linenum
)) != NULL
) {
1171 char *cmd
, *saveptr
;
1173 if (line
[0] == '\0' || line
[0] == '#')
1176 cmd
= strtok_r(line
, "\t ", &saveptr
);
1180 if (streq(cmd
, "search")) {
1182 while ((sp
= strtok_r(NULL
, "\t ", &saveptr
)) != NULL
) {
1183 uint8_t builtin
= streq(sp
, CFG_BUILTIN_KEY
);
1184 cfg_search_add(cfg
, sp
, builtin
);
1186 } else if (streq(cmd
, "override")) {
1187 const char *modname
= strtok_r(NULL
, "\t ", &saveptr
);
1188 const char *version
= strtok_r(NULL
, "\t ", &saveptr
);
1189 const char *subdir
= strtok_r(NULL
, "\t ", &saveptr
);
1191 if (modname
== NULL
|| version
== NULL
||
1195 if (!cfg_kernel_matches(cfg
, version
)) {
1196 INF("%s:%u: override kernel did not match %s\n",
1197 filename
, linenum
, version
);
1201 cfg_override_add(cfg
, modname
, subdir
);
1202 } else if (streq(cmd
, "include")
1203 || streq(cmd
, "make_map_files")) {
1204 INF("%s:%u: command %s not implemented yet\n",
1205 filename
, linenum
, cmd
);
1208 ERR("%s:%u: ignoring bad line starting with '%s'\n",
1209 filename
, linenum
, cmd
);
1221 static int cfg_files_filter_out(DIR *d
, const char *dir
, const char *name
)
1223 size_t len
= strlen(name
);
1229 if (len
< 6 || !streq(name
+ len
- 5, ".conf")) {
1230 INF("All cfg files need .conf: %s/%s\n", dir
, name
);
1234 fstatat(dirfd(d
), name
, &st
, 0);
1235 if (S_ISDIR(st
.st_mode
)) {
1236 ERR("Directories inside directories are not supported: %s/%s\n",
1251 static void cfg_file_free(struct cfg_file
*f
)
1256 static int cfg_files_insert_sorted(struct cfg_file
***p_files
, size_t *p_n_files
,
1257 const char *dir
, const char *name
)
1259 struct cfg_file
**files
, *f
;
1260 size_t i
, n_files
, namelen
, dirlen
;
1263 dirlen
= strlen(dir
);
1265 namelen
= strlen(name
);
1267 name
= basename(dir
);
1268 namelen
= strlen(name
);
1269 dirlen
-= namelen
- 1;
1272 n_files
= *p_n_files
;
1274 for (i
= 0; i
< n_files
; i
++) {
1275 int cmp
= strcmp(name
, files
[i
]->name
);
1277 DBG("Ignoring duplicate config file: %.*s/%s\n",
1278 (int)dirlen
, dir
, name
);
1284 f
= malloc(sizeof(struct cfg_file
) + dirlen
+ namelen
+ 2);
1286 ERR("files insert sorted: out of memory\n");
1290 tmp
= realloc(files
, sizeof(struct cfg_file
*) * (n_files
+ 1));
1292 ERR("files insert sorted: out of memory\n");
1296 *p_files
= files
= tmp
;
1299 memmove(files
+ i
+ 1, files
+ i
,
1300 sizeof(struct cfg_file
*) * (n_files
- i
));
1305 f
->namelen
= namelen
;
1306 f
->name
= f
->path
+ dirlen
+ 1;
1307 memcpy(f
->path
, dir
, dirlen
);
1308 f
->path
[dirlen
] = '/';
1309 memcpy(f
->path
+ dirlen
+ 1, name
, namelen
);
1310 f
->path
[dirlen
+ 1 + namelen
] = '\0';
1312 *p_n_files
= n_files
+ 1;
1317 * Insert configuration files ignoring duplicates
1319 static int cfg_files_list(struct cfg_file
***p_files
, size_t *p_n_files
,
1326 if (stat(path
, &st
) != 0) {
1328 DBG("could not stat '%s': %m\n", path
);
1332 if (S_ISREG(st
.st_mode
)) {
1333 cfg_files_insert_sorted(p_files
, p_n_files
, path
, NULL
);
1335 } if (!S_ISDIR(st
.st_mode
)) {
1336 ERR("unsupported file mode %s: %#x\n", path
, st
.st_mode
);
1342 ERR("files list %s: %m\n", path
);
1347 struct dirent ent
, *entp
;
1349 err
= readdir_r(d
, &ent
, &entp
);
1351 ERR("reading entry %s\n", strerror(-err
));
1356 if (cfg_files_filter_out(d
, path
, entp
->d_name
))
1359 cfg_files_insert_sorted(p_files
, p_n_files
, path
, entp
->d_name
);
1363 DBG("parsed configuration files from %s: %s\n", path
, strerror(-err
));
1367 static int cfg_load(struct cfg
*cfg
, const char * const *cfg_paths
)
1369 size_t i
, n_files
= 0;
1370 struct cfg_file
**files
= NULL
;
1372 if (cfg_paths
== NULL
)
1373 cfg_paths
= default_cfg_paths
;
1375 for (i
= 0; cfg_paths
[i
] != NULL
; i
++)
1376 cfg_files_list(&files
, &n_files
, cfg_paths
[i
]);
1378 for (i
= 0; i
< n_files
; i
++) {
1379 struct cfg_file
*f
= files
[i
];
1380 cfg_file_parse(cfg
, f
->path
);
1385 /* For backward compatibility add "updates" to the head of the search
1386 * list here. But only if there was no "search" option specified.
1388 if (cfg
->searches
== NULL
)
1389 cfg_search_add(cfg
, "updates", 0);
1394 static void cfg_free(struct cfg
*cfg
)
1396 while (cfg
->overrides
) {
1397 struct cfg_override
*tmp
= cfg
->overrides
;
1398 cfg
->overrides
= cfg
->overrides
->next
;
1399 cfg_override_free(tmp
);
1402 while (cfg
->searches
) {
1403 struct cfg_search
*tmp
= cfg
->searches
;
1404 cfg
->searches
= cfg
->searches
->next
;
1405 cfg_search_free(tmp
);
1410 /* depmod calculations ***********************************************/
1412 struct kmod_module
*kmod
;
1414 const char *relpath
; /* path relative to '$ROOT/lib/modules/$VER/' */
1415 struct array deps
; /* struct symbol */
1416 size_t baselen
; /* points to start of basename/filename */
1418 int sort_idx
; /* sort index using modules.order */
1419 int dep_sort_idx
; /* topological sort index */
1420 uint16_t idx
; /* index in depmod->modules.array */
1421 uint16_t users
; /* how many modules depend on this one */
1422 uint8_t dep_loop
: 1;
1433 const struct cfg
*cfg
;
1434 struct kmod_ctx
*ctx
;
1435 struct array modules
;
1436 struct hash
*modules_by_relpath
;
1437 struct hash
*modules_by_name
;
1438 struct hash
*symbols
;
1439 unsigned int dep_loops
;
1442 static void mod_free(struct mod
*mod
)
1444 DBG("free %p kmod=%p, path=%s\n", mod
, mod
->kmod
, mod
->path
);
1445 array_free_array(&mod
->deps
);
1446 kmod_module_unref(mod
->kmod
);
1450 static int mod_add_dependency(struct mod
*mod
, struct symbol
*sym
)
1454 DBG("%s depends on %s %s\n", mod
->path
, sym
->name
,
1455 sym
->owner
!= NULL
? sym
->owner
->path
: "(unknown)");
1457 if (sym
->owner
== NULL
)
1460 err
= array_append_unique(&mod
->deps
, sym
->owner
);
1466 sym
->owner
->users
++;
1467 SHOW("%s needs \"%s\": %s\n", mod
->path
, sym
->name
, sym
->owner
->path
);
1471 static void symbol_free(struct symbol
*sym
)
1473 DBG("free %p sym=%s, owner=%p %s\n", sym
, sym
->name
, sym
->owner
,
1474 sym
->owner
!= NULL
? sym
->owner
->path
: "");
1478 static int depmod_init(struct depmod
*depmod
, struct cfg
*cfg
, struct kmod_ctx
*ctx
)
1485 array_init(&depmod
->modules
, 128);
1487 depmod
->modules_by_relpath
= hash_new(512, NULL
);
1488 if (depmod
->modules_by_relpath
== NULL
) {
1490 goto modules_by_relpath_failed
;
1493 depmod
->modules_by_name
= hash_new(512, NULL
);
1494 if (depmod
->modules_by_name
== NULL
) {
1496 goto modules_by_name_failed
;
1499 depmod
->symbols
= hash_new(2048, (void (*)(void *))symbol_free
);
1500 if (depmod
->symbols
== NULL
) {
1502 goto symbols_failed
;
1508 hash_free(depmod
->modules_by_name
);
1509 modules_by_name_failed
:
1510 hash_free(depmod
->modules_by_relpath
);
1511 modules_by_relpath_failed
:
1515 static void depmod_shutdown(struct depmod
*depmod
)
1519 hash_free(depmod
->symbols
);
1521 hash_free(depmod
->modules_by_relpath
);
1523 hash_free(depmod
->modules_by_name
);
1525 for (i
= 0; i
< depmod
->modules
.count
; i
++)
1526 mod_free(depmod
->modules
.array
[i
]);
1527 array_free_array(&depmod
->modules
);
1529 kmod_unref(depmod
->ctx
);
1532 static int depmod_module_add(struct depmod
*depmod
, struct kmod_module
*kmod
)
1534 const struct cfg
*cfg
= depmod
->cfg
;
1535 const char *modname
;
1540 modname
= kmod_module_get_name(kmod
);
1541 modnamelen
= strlen(modname
) + 1;
1543 mod
= calloc(1, sizeof(struct mod
) + modnamelen
);
1547 mod
->sort_idx
= depmod
->modules
.count
+ 1;
1548 mod
->dep_sort_idx
= INT32_MAX
;
1549 mod
->idx
= depmod
->modules
.count
;
1550 memcpy(mod
->modname
, modname
, modnamelen
);
1551 mod
->modnamelen
= modnamelen
;
1553 array_init(&mod
->deps
, 4);
1555 mod
->path
= kmod_module_get_path(kmod
);
1556 mod
->baselen
= strrchr(mod
->path
, '/') - mod
->path
+ 1;
1557 if (strncmp(mod
->path
, cfg
->dirname
, cfg
->dirnamelen
) == 0 &&
1558 mod
->path
[cfg
->dirnamelen
] == '/')
1559 mod
->relpath
= mod
->path
+ cfg
->dirnamelen
+ 1;
1561 mod
->relpath
= NULL
;
1563 err
= array_append(&depmod
->modules
, mod
);
1569 err
= hash_add_unique(depmod
->modules_by_name
, mod
->modname
, mod
);
1571 ERR("hash_add_unique %s: %s\n", mod
->modname
, strerror(-err
));
1572 array_pop(&depmod
->modules
);
1577 if (mod
->relpath
!= NULL
) {
1578 err
= hash_add_unique(depmod
->modules_by_relpath
,
1581 ERR("hash_add_unique %s: %s\n",
1582 mod
->relpath
, strerror(-err
));
1583 hash_del(depmod
->modules_by_name
, mod
->modname
);
1584 array_pop(&depmod
->modules
);
1590 DBG("add %p kmod=%p, path=%s\n", mod
, kmod
, mod
->path
);
1595 static int depmod_module_replace(struct depmod
*depmod
, struct mod
*mod
, struct kmod_module
*kmod
)
1597 const struct cfg
*cfg
= depmod
->cfg
;
1598 const char *path
, *relpath
;
1601 path
= kmod_module_get_path(kmod
);
1602 if (strncmp(path
, cfg
->dirname
, cfg
->dirnamelen
) == 0 &&
1603 path
[cfg
->dirnamelen
] == '/')
1604 relpath
= path
+ cfg
->dirnamelen
+ 1;
1608 if (relpath
!= NULL
) {
1609 err
= hash_add_unique(depmod
->modules_by_relpath
, relpath
, mod
);
1611 ERR("hash_add_unique %s: %s\n",
1612 relpath
, strerror(-err
));
1617 if (mod
->relpath
!= NULL
)
1618 hash_del(depmod
->modules_by_relpath
, mod
->relpath
);
1619 kmod_module_unref(mod
->kmod
);
1620 mod
->relpath
= relpath
;
1626 /* returns if existing module @mod is higher priority than newpath.
1627 * note this is the inverse of module-init-tools is_higher_priority()
1629 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
)
1631 const struct cfg
*cfg
= depmod
->cfg
;
1632 const struct cfg_override
*ov
;
1633 const struct cfg_search
*se
;
1634 size_t newlen
= baselen
+ modnamelen
;
1635 size_t oldlen
= mod
->baselen
+ mod
->modnamelen
;
1636 const char *oldpath
= mod
->path
;
1637 int i
, bprio
= -1, oldprio
= -1, newprio
= -1;
1639 DBG("comparing priorities of %s and %s\n",
1642 for (ov
= cfg
->overrides
; ov
!= NULL
; ov
= ov
->next
) {
1643 DBG("override %s\n", ov
->path
);
1644 if (newlen
== ov
->len
&& memcmp(ov
->path
, newpath
, newlen
) == 0)
1646 if (oldlen
== ov
->len
&& memcmp(ov
->path
, oldpath
, oldlen
) == 0)
1650 for (i
= 0, se
= cfg
->searches
; se
!= NULL
; se
= se
->next
, i
++) {
1651 DBG("search %s\n", se
->builtin
? "built-in" : se
->path
);
1654 else if (newlen
>= se
->len
&&
1655 memcmp(se
->path
, newpath
, se
->len
) == 0)
1657 else if (oldlen
>= se
->len
&&
1658 memcmp(se
->path
, oldpath
, se
->len
) == 0)
1667 DBG("priorities: built-in: %d, old: %d, new: %d\n",
1668 bprio
, newprio
, oldprio
);
1670 return newprio
<= oldprio
;
1673 static int depmod_modules_search_file(struct depmod
*depmod
, size_t baselen
, size_t namelen
, const char *path
)
1675 struct kmod_module
*kmod
;
1677 const char *relpath
, *modname
;
1678 const struct kmod_ext
*eitr
;
1680 uint8_t matches
= 0;
1683 for (eitr
= kmod_exts
; eitr
->ext
!= NULL
; eitr
++) {
1684 if (namelen
<= eitr
->len
)
1686 if (streq(path
+ baselen
+ namelen
- eitr
->len
, eitr
->ext
)) {
1694 relpath
= path
+ depmod
->cfg
->dirnamelen
+ 1;
1695 DBG("try %s\n", relpath
);
1697 err
= kmod_module_new_from_path(depmod
->ctx
, path
, &kmod
);
1699 ERR("Could not create module %s: %s\n",
1700 path
, strerror(-err
));
1704 modname
= kmod_module_get_name(kmod
);
1705 mod
= hash_find(depmod
->modules_by_name
, modname
);
1707 err
= depmod_module_add(depmod
, kmod
);
1709 ERR("Could not add module %s: %s\n",
1710 path
, strerror(-err
));
1711 kmod_module_unref(kmod
);
1717 modnamelen
= strlen(modname
);
1718 if (depmod_module_is_higher_priority(depmod
, mod
, baselen
,
1719 namelen
, modnamelen
, path
)) {
1720 DBG("Ignored lower priority: %s, higher: %s\n",
1722 kmod_module_unref(kmod
);
1726 err
= depmod_module_replace(depmod
, mod
, kmod
);
1728 ERR("Could not replace existing module %s\n", path
);
1729 kmod_module_unref(kmod
);
1736 static int depmod_modules_search_dir(struct depmod
*depmod
, DIR *d
, size_t baselen
, char *path
)
1739 int err
= 0, dfd
= dirfd(d
);
1741 while ((de
= readdir(d
)) != NULL
) {
1742 const char *name
= de
->d_name
;
1746 if (name
[0] == '.' && (name
[1] == '\0' ||
1747 (name
[1] == '.' && name
[2] == '\0')))
1749 if (streq(name
, "build") || streq(name
, "source"))
1751 namelen
= strlen(name
);
1752 if (baselen
+ namelen
+ 2 >= PATH_MAX
) {
1753 path
[baselen
] = '\0';
1754 ERR("path is too long %s%s %zd\n", path
, name
);
1757 memcpy(path
+ baselen
, name
, namelen
+ 1);
1759 if (de
->d_type
== DT_REG
)
1761 else if (de
->d_type
== DT_DIR
)
1765 if (fstatat(dfd
, name
, &st
, 0) < 0) {
1766 ERR("fstatat(%d, %s): %m\n", dfd
, name
);
1768 } else if (S_ISREG(st
.st_mode
))
1770 else if (S_ISDIR(st
.st_mode
))
1773 ERR("unsupported file type %s: %o\n",
1774 path
, st
.st_mode
& S_IFMT
);
1782 if (baselen
+ namelen
+ 2 + NAME_MAX
>= PATH_MAX
) {
1783 ERR("directory path is too long %s\n", path
);
1786 fd
= openat(dfd
, name
, O_RDONLY
);
1788 ERR("openat(%d, %s, O_RDONLY): %m\n",
1792 subdir
= fdopendir(fd
);
1793 if (subdir
== NULL
) {
1794 ERR("fdopendir(%d): %m\n", fd
);
1798 path
[baselen
+ namelen
] = '/';
1799 path
[baselen
+ namelen
+ 1] = '\0';
1800 err
= depmod_modules_search_dir(depmod
, subdir
,
1801 baselen
+ namelen
+ 1,
1805 err
= depmod_modules_search_file(depmod
, baselen
,
1810 path
[baselen
+ namelen
] = '\0';
1811 ERR("failed %s: %s\n", path
, strerror(-err
));
1812 err
= 0; /* ignore errors */
1819 static int depmod_modules_search(struct depmod
*depmod
)
1821 char path
[PATH_MAX
];
1822 DIR *d
= opendir(depmod
->cfg
->dirname
);
1827 ERR("Couldn't open directory %s: %m\n", depmod
->cfg
->dirname
);
1831 baselen
= depmod
->cfg
->dirnamelen
;
1832 memcpy(path
, depmod
->cfg
->dirname
, baselen
);
1833 path
[baselen
] = '/';
1835 path
[baselen
] = '\0';
1837 err
= depmod_modules_search_dir(depmod
, d
, baselen
, path
);
1842 static int mod_cmp(const void *pa
, const void *pb
) {
1843 const struct mod
*a
= *(const struct mod
**)pa
;
1844 const struct mod
*b
= *(const struct mod
**)pb
;
1845 if (a
->dep_loop
== b
->dep_loop
)
1846 return a
->sort_idx
- b
->sort_idx
;
1847 else if (a
->dep_loop
)
1849 else if (b
->dep_loop
)
1851 return a
->sort_idx
- b
->sort_idx
;
1854 static void depmod_modules_sort(struct depmod
*depmod
)
1856 char order_file
[PATH_MAX
], line
[PATH_MAX
];
1858 unsigned idx
= 0, total
= 0;
1860 snprintf(order_file
, sizeof(order_file
), "%s/modules.order",
1861 depmod
->cfg
->dirname
);
1862 fp
= fopen(order_file
, "r");
1864 ERR("could not open %s: %m\n", order_file
);
1868 while (fgets(line
, sizeof(line
), fp
) != NULL
) {
1869 size_t len
= strlen(line
);
1873 if (line
[len
- 1] != '\n') {
1874 ERR("%s:%u corrupted line misses '\\n'\n",
1881 fseek(fp
, 0, SEEK_SET
);
1882 while (fgets(line
, sizeof(line
), fp
) != NULL
) {
1883 size_t len
= strlen(line
);
1889 line
[len
- 1] = '\0';
1891 mod
= hash_find(depmod
->modules_by_relpath
, line
);
1894 mod
->sort_idx
= idx
- total
;
1897 array_sort(&depmod
->modules
, mod_cmp
);
1898 for (idx
= 0; idx
< depmod
->modules
.count
; idx
++) {
1899 struct mod
*m
= depmod
->modules
.array
[idx
];
1907 static int depmod_symbol_add(struct depmod
*depmod
, const char *name
, uint64_t crc
, const struct mod
*owner
)
1913 if (name
[0] == depmod
->cfg
->sym_prefix
)
1916 namelen
= strlen(name
) + 1;
1917 sym
= malloc(sizeof(struct symbol
) + namelen
);
1921 sym
->owner
= (struct mod
*)owner
;
1923 memcpy(sym
->name
, name
, namelen
);
1925 err
= hash_add(depmod
->symbols
, sym
->name
, sym
);
1931 DBG("add %p sym=%s, owner=%p %s\n", sym
, sym
->name
, owner
,
1932 owner
!= NULL
? owner
->path
: "");
1937 static struct symbol
*depmod_symbol_find(const struct depmod
*depmod
, const char *name
)
1939 if (name
[0] == '.') /* PPC64 needs this: .foo == foo */
1941 if (name
[0] == depmod
->cfg
->sym_prefix
)
1943 return hash_find(depmod
->symbols
, name
);
1946 static int depmod_load_symbols(struct depmod
*depmod
)
1948 const struct mod
**itr
, **itr_end
;
1950 DBG("load symbols (%zd modules)\n", depmod
->modules
.count
);
1952 itr
= (const struct mod
**)depmod
->modules
.array
;
1953 itr_end
= itr
+ depmod
->modules
.count
;
1954 for (; itr
< itr_end
; itr
++) {
1955 const struct mod
*mod
= *itr
;
1956 struct kmod_list
*l
, *list
= NULL
;
1957 int err
= kmod_module_get_symbols(mod
->kmod
, &list
);
1959 DBG("ignoring %s: no symbols: %s\n",
1960 mod
->path
, strerror(-err
));
1963 kmod_list_foreach(l
, list
) {
1964 const char *name
= kmod_module_symbol_get_symbol(l
);
1965 uint64_t crc
= kmod_module_symbol_get_crc(l
);
1966 depmod_symbol_add(depmod
, name
, crc
, mod
);
1968 kmod_module_symbols_free_list(list
);
1971 DBG("loaded symbols (%zd modules, %zd symbols)\n",
1972 depmod
->modules
.count
, hash_get_count(depmod
->symbols
));
1977 static int depmod_load_module_dependencies(struct depmod
*depmod
, struct mod
*mod
)
1979 const struct cfg
*cfg
= depmod
->cfg
;
1980 struct kmod_list
*l
, *list
= NULL
;
1981 int err
= kmod_module_get_dependency_symbols(mod
->kmod
, &list
);
1983 DBG("ignoring %s: no dependency symbols: %s\n",
1984 mod
->path
, strerror(-err
));
1988 DBG("do dependencies of %s\n", mod
->path
);
1989 kmod_list_foreach(l
, list
) {
1990 const char *name
= kmod_module_dependency_symbol_get_symbol(l
);
1991 uint64_t crc
= kmod_module_dependency_symbol_get_crc(l
);
1992 int bindtype
= kmod_module_dependency_symbol_get_bind(l
);
1993 struct symbol
*sym
= depmod_symbol_find(depmod
, name
);
1994 uint8_t is_weak
= bindtype
== KMOD_SYMBOL_WEAK
;
1997 DBG("%s needs (%c) unknown symbol %s\n",
1998 mod
->path
, bindtype
, name
);
1999 if (cfg
->print_unknown
&& !is_weak
)
2000 WRN("%s needs unknown symbol %s\n",
2005 if (cfg
->check_symvers
&& sym
->crc
!= crc
&& !is_weak
) {
2006 DBG("symbol %s (%#"PRIx64
") module %s (%#"PRIx64
")\n",
2007 sym
->name
, sym
->crc
, mod
->path
, crc
);
2008 if (cfg
->print_unknown
)
2009 WRN("%s disagrees about version of symbol %s\n",
2013 mod_add_dependency(mod
, sym
);
2015 kmod_module_dependency_symbols_free_list(list
);
2019 static int depmod_load_dependencies(struct depmod
*depmod
)
2021 struct mod
**itr
, **itr_end
;
2023 DBG("load dependencies (%zd modules, %zd symbols)\n",
2024 depmod
->modules
.count
, hash_get_count(depmod
->symbols
));
2026 itr
= (struct mod
**)depmod
->modules
.array
;
2027 itr_end
= itr
+ depmod
->modules
.count
;
2028 for (; itr
< itr_end
; itr
++) {
2029 struct mod
*mod
= *itr
;
2030 depmod_load_module_dependencies(depmod
, mod
);
2033 DBG("loaded dependencies (%zd modules, %zd symbols)\n",
2034 depmod
->modules
.count
, hash_get_count(depmod
->symbols
));
2039 static int dep_cmp(const void *pa
, const void *pb
)
2041 const struct mod
*a
= *(const struct mod
**)pa
;
2042 const struct mod
*b
= *(const struct mod
**)pb
;
2043 if (a
->dep_loop
== b
->dep_loop
)
2044 return a
->dep_sort_idx
- b
->dep_sort_idx
;
2045 else if (a
->dep_loop
)
2047 else if (b
->dep_loop
)
2049 return a
->dep_sort_idx
- b
->dep_sort_idx
;
2052 static void depmod_sort_dependencies(struct depmod
*depmod
)
2054 struct mod
**itr
, **itr_end
;
2055 itr
= (struct mod
**)depmod
->modules
.array
;
2056 itr_end
= itr
+ depmod
->modules
.count
;
2057 for (; itr
< itr_end
; itr
++) {
2058 struct mod
*m
= *itr
;
2059 if (m
->deps
.count
> 1)
2060 array_sort(&m
->deps
, dep_cmp
);
2064 static int depmod_calculate_dependencies(struct depmod
*depmod
)
2066 const struct mod
**itrm
;
2067 uint16_t *users
, *roots
, *sorted
;
2068 uint16_t i
, n_roots
= 0, n_sorted
= 0, n_mods
= depmod
->modules
.count
;
2070 users
= malloc(sizeof(uint16_t) * n_mods
* 3);
2073 roots
= users
+ n_mods
;
2074 sorted
= roots
+ n_mods
;
2076 DBG("calculate dependencies and ordering (%zd modules)\n", n_mods
);
2078 assert(depmod
->modules
.count
< UINT16_MAX
);
2080 /* populate modules users (how many modules uses it) */
2081 itrm
= (const struct mod
**)depmod
->modules
.array
;
2082 for (i
= 0; i
< n_mods
; i
++, itrm
++) {
2083 const struct mod
*m
= *itrm
;
2084 users
[i
] = m
->users
;
2085 if (users
[i
] == 0) {
2091 /* topological sort (outputs modules without users first) */
2092 while (n_roots
> 0) {
2093 const struct mod
**itr_dst
, **itr_dst_end
;
2095 uint16_t src_idx
= roots
[--n_roots
];
2097 src
= depmod
->modules
.array
[src_idx
];
2098 src
->dep_sort_idx
= n_sorted
;
2099 sorted
[n_sorted
] = src_idx
;
2102 itr_dst
= (const struct mod
**)src
->deps
.array
;
2103 itr_dst_end
= itr_dst
+ src
->deps
.count
;
2104 for (; itr_dst
< itr_dst_end
; itr_dst
++) {
2105 const struct mod
*dst
= *itr_dst
;
2106 uint16_t dst_idx
= dst
->idx
;
2107 assert(users
[dst_idx
] > 0);
2109 if (users
[dst_idx
] == 0) {
2110 roots
[n_roots
] = dst_idx
;
2116 if (n_sorted
< n_mods
) {
2117 WRN("found %hu modules in dependency cycles!\n",
2119 for (i
= 0; i
< n_mods
; i
++) {
2123 m
= depmod
->modules
.array
[i
];
2124 WRN("%s in dependency cycle!\n", m
->path
);
2126 m
->dep_sort_idx
= INT32_MAX
;
2127 depmod
->dep_loops
++;
2131 depmod_sort_dependencies(depmod
);
2133 DBG("calculated dependencies and ordering (%u loops, %zd modules)\n",
2134 depmod
->dep_loops
, n_mods
);
2140 static int depmod_load(struct depmod
*depmod
)
2144 err
= depmod_load_symbols(depmod
);
2148 err
= depmod_load_dependencies(depmod
);
2152 err
= depmod_calculate_dependencies(depmod
);
2159 static size_t mod_count_all_dependencies(const struct mod
*mod
)
2161 size_t i
, count
= 0;
2162 for (i
= 0; i
< mod
->deps
.count
; i
++) {
2163 const struct mod
*d
= mod
->deps
.array
[i
];
2164 count
+= 1 + mod_count_all_dependencies(d
);
2169 static int mod_fill_all_unique_dependencies(const struct mod
*mod
, const struct mod
**deps
, size_t n_deps
, size_t *last
)
2173 for (i
= 0; i
< mod
->deps
.count
; i
++) {
2174 const struct mod
*d
= mod
->deps
.array
[i
];
2178 for (j
= 0; j
< *last
; j
++) {
2188 if (*last
>= n_deps
)
2192 err
= mod_fill_all_unique_dependencies(d
, deps
, n_deps
, last
);
2199 static const struct mod
**mod_get_all_sorted_dependencies(const struct mod
*mod
, size_t *n_deps
)
2201 const struct mod
**deps
;
2204 *n_deps
= mod_count_all_dependencies(mod
);
2208 deps
= malloc(sizeof(struct mod
*) * (*n_deps
));
2212 if (mod_fill_all_unique_dependencies(mod
, deps
, *n_deps
, &last
) < 0) {
2217 qsort(deps
, last
, sizeof(struct mod
*), dep_cmp
);
2222 static inline const char *mod_get_compressed_path(const struct mod
*mod
)
2224 if (mod
->relpath
!= NULL
)
2225 return mod
->relpath
;
2229 static int output_deps(struct depmod
*depmod
, FILE *out
)
2233 for (i
= 0; i
< depmod
->modules
.count
; i
++) {
2234 const struct mod
**deps
, *mod
= depmod
->modules
.array
[i
];
2235 const char *p
= mod_get_compressed_path(mod
);
2238 if (mod
->dep_loop
) {
2239 DBG("Ignored %s due dependency loops\n", p
);
2243 fprintf(out
, "%s:", p
);
2245 if (mod
->deps
.count
== 0)
2248 deps
= mod_get_all_sorted_dependencies(mod
, &n_deps
);
2250 ERR("Could not get all sorted dependencies of %s\n", p
);
2254 for (j
= 0; j
< n_deps
; j
++) {
2255 const struct mod
*d
= deps
[j
];
2257 DBG("Ignored %s (dependency of %s) "
2258 "due dependency loops\n",
2259 mod_get_compressed_path(d
), p
);
2262 fprintf(out
, " %s", mod_get_compressed_path(d
));
2272 static int output_deps_bin(struct depmod
*depmod
, FILE *out
)
2274 struct index_node
*idx
;
2280 idx
= index_create();
2284 for (i
= 0; i
< depmod
->modules
.count
; i
++) {
2285 const struct mod
**deps
, *mod
= depmod
->modules
.array
[i
];
2286 const char *p
= mod_get_compressed_path(mod
);
2288 size_t j
, n_deps
, linepos
, linelen
, slen
;
2291 if (mod
->dep_loop
) {
2292 DBG("Ignored %s due dependency loops\n", p
);
2296 deps
= mod_get_all_sorted_dependencies(mod
, &n_deps
);
2297 if (deps
== NULL
&& n_deps
> 0) {
2298 ERR("Could not get all sorted dependencies of %s\n", p
);
2302 linelen
= strlen(p
) + 1;
2303 for (j
= 0; j
< n_deps
; j
++) {
2304 const struct mod
*d
= deps
[j
];
2306 DBG("Ignored %s (dependency of %s) "
2307 "due dependency loops\n",
2308 mod_get_compressed_path(d
), p
);
2311 linelen
+= 1 + strlen(mod_get_compressed_path(d
));
2314 line
= malloc(linelen
+ 1);
2317 ERR("modules.deps.bin: out of memory\n");
2323 memcpy(line
+ linepos
, p
, slen
);
2325 line
[linepos
] = ':';
2328 for (j
= 0; j
< n_deps
; j
++) {
2329 const struct mod
*d
= deps
[j
];
2333 line
[linepos
] = ' ';
2336 dp
= mod_get_compressed_path(d
);
2338 memcpy(line
+ linepos
, dp
, slen
);
2341 line
[linepos
] = '\0';
2343 duplicate
= index_insert(idx
, mod
->modname
, line
, mod
->idx
);
2344 if (duplicate
&& depmod
->cfg
->warn_dups
)
2345 WRN("duplicate module deps:\n%s\n", line
);
2350 index_write(idx
, out
);
2356 static int output_aliases(struct depmod
*depmod
, FILE *out
)
2360 fputs("# Aliases extracted from modules themselves.\n", out
);
2362 for (i
= 0; i
< depmod
->modules
.count
; i
++) {
2363 const struct mod
*mod
= depmod
->modules
.array
[i
];
2364 struct kmod_list
*l
, *list
= NULL
;
2365 int r
= kmod_module_get_info(mod
->kmod
, &list
);
2366 if (r
< 0 || list
== NULL
)
2368 kmod_list_foreach(l
, list
) {
2369 const char *key
= kmod_module_info_get_key(l
);
2370 const char *value
= kmod_module_info_get_value(l
);
2372 if (!streq(key
, "alias"))
2375 fprintf(out
, "alias %s %s\n",
2376 value
, kmod_module_get_name(mod
->kmod
));
2378 kmod_module_info_free_list(list
);
2384 static int output_aliases_bin(struct depmod
*depmod
, FILE *out
)
2387 struct index_node
*idx
;
2393 idx
= index_create();
2397 for (i
= 0; i
< depmod
->modules
.count
; i
++) {
2398 const struct mod
*mod
= depmod
->modules
.array
[i
];
2399 struct kmod_list
*l
, *list
= NULL
;
2400 int r
= kmod_module_get_info(mod
->kmod
, &list
);
2401 if (r
< 0 || list
== NULL
)
2403 kmod_list_foreach(l
, list
) {
2404 const char *key
= kmod_module_info_get_key(l
);
2405 const char *value
= kmod_module_info_get_value(l
);
2406 const char *modname
, *alias
;
2409 if (!streq(key
, "alias"))
2412 alias
= underscores(value
, buf
, sizeof(buf
));
2416 modname
= kmod_module_get_name(mod
->kmod
);
2417 duplicate
= index_insert(idx
, alias
, modname
,
2419 if (duplicate
&& depmod
->cfg
->warn_dups
)
2420 WRN("duplicate module alias:\n%s %s\n",
2423 kmod_module_info_free_list(list
);
2426 index_write(idx
, out
);
2432 static int output_softdeps(struct depmod
*depmod
, FILE *out
)
2436 fputs("# Soft dependencies extracted from modules themselves.\n", out
);
2437 fputs("# Copy, with a .conf extension, to /etc/modprobe.d to use "
2438 "it with modprobe.\n", out
);
2440 for (i
= 0; i
< depmod
->modules
.count
; i
++) {
2441 const struct mod
*mod
= depmod
->modules
.array
[i
];
2442 struct kmod_list
*l
, *list
= NULL
;
2443 int r
= kmod_module_get_info(mod
->kmod
, &list
);
2444 if (r
< 0 || list
== NULL
)
2446 kmod_list_foreach(l
, list
) {
2447 const char *key
= kmod_module_info_get_key(l
);
2448 const char *value
= kmod_module_info_get_value(l
);
2450 if (!streq(key
, "softdep"))
2453 fprintf(out
, "softdep %s %s\n",
2454 kmod_module_get_name(mod
->kmod
), value
);
2456 kmod_module_info_free_list(list
);
2462 static int output_symbols(struct depmod
*depmod
, FILE *out
)
2466 fputs("# Aliases for symbols, used by symbol_request().\n", out
);
2468 for (i
= 0; i
< depmod
->symbols
->n_buckets
; i
++) {
2469 const struct hash_bucket
*b
= depmod
->symbols
->buckets
+ i
;
2471 for (j
= 0; j
< b
->used
; j
++) {
2472 const struct hash_entry
*e
= b
->entries
+ j
;
2473 const struct symbol
*sym
= e
->value
;
2474 if (sym
->owner
== NULL
)
2476 fprintf(out
, "alias symbol:%s %s\n",
2477 sym
->name
, sym
->owner
->modname
);
2484 static int output_symbols_bin(struct depmod
*depmod
, FILE *out
)
2486 struct index_node
*idx
;
2488 size_t i
, baselen
= sizeof("symbol:") - 1;
2493 idx
= index_create();
2497 memcpy(alias
, "symbol:", baselen
);
2499 for (i
= 0; i
< depmod
->symbols
->n_buckets
; i
++) {
2500 const struct hash_bucket
*b
= depmod
->symbols
->buckets
+ i
;
2502 for (j
= 0; j
< b
->used
; j
++) {
2503 const struct hash_entry
*e
= b
->entries
+ j
;
2504 const struct symbol
*sym
= e
->value
;
2507 if (sym
->owner
== NULL
)
2510 strcpy(alias
+ baselen
, sym
->name
);
2511 duplicate
= index_insert(idx
, alias
,
2512 sym
->owner
->modname
,
2514 if (duplicate
&& depmod
->cfg
->warn_dups
)
2515 WRN("duplicate module syms:\n%s %s\n",
2516 alias
, sym
->owner
->modname
);
2520 index_write(idx
, out
);
2525 static int output_builtin_bin(struct depmod
*depmod
, FILE *out
)
2528 struct index_node
*idx
;
2529 char infile
[PATH_MAX
], line
[PATH_MAX
], modname
[NAME_MAX
];
2534 snprintf(infile
, sizeof(infile
), "%s/modules.builtin",
2535 depmod
->cfg
->dirname
);
2536 in
= fopen(infile
, "r");
2539 ERR("Could not open %s: %m\n", infile
);
2543 idx
= index_create();
2549 while (fgets(line
, sizeof(line
), in
) != NULL
) {
2550 if (!isalpha(line
[0])) {
2551 ERR("Invalid modules.builtin line: %s\n", line
);
2555 path_to_modname(line
, modname
, NULL
);
2556 index_insert(idx
, modname
, "", 0);
2559 index_write(idx
, out
);
2566 static int output_devname(struct depmod
*depmod
, FILE *out
)
2570 fputs("# Device nodes to trigger on-demand module loading.\n", out
);
2572 for (i
= 0; i
< depmod
->modules
.count
; i
++) {
2573 const struct mod
*mod
= depmod
->modules
.array
[i
];
2574 struct kmod_list
*l
, *list
= NULL
;
2575 const char *devname
= NULL
;
2577 unsigned int major
= 0, minor
= 0;
2580 r
= kmod_module_get_info(mod
->kmod
, &list
);
2581 if (r
< 0 || list
== NULL
)
2584 kmod_list_foreach(l
, list
) {
2585 const char *key
= kmod_module_info_get_key(l
);
2586 const char *value
= kmod_module_info_get_value(l
);
2587 unsigned int maj
, min
;
2589 if (!streq(key
, "alias"))
2592 if (strstartswith(value
, "devname:"))
2593 devname
= value
+ sizeof("devname:") - 1;
2594 else if (sscanf(value
, "char-major-%u-%u",
2599 } else if (sscanf(value
, "block-major-%u-%u",
2606 if (type
!= '\0' && devname
!= NULL
) {
2607 fprintf(out
, "%s %s %c%u:%u\n",
2608 kmod_module_get_name(mod
->kmod
),
2609 devname
, type
, major
, minor
);
2613 kmod_module_info_free_list(list
);
2619 static int depmod_output(struct depmod
*depmod
, FILE *out
)
2621 static const struct depfile
{
2623 int (*cb
)(struct depmod
*depmod
, FILE *out
);
2624 } *itr
, depfiles
[] = {
2625 {"modules.dep", output_deps
},
2626 {"modules.dep.bin", output_deps_bin
},
2627 {"modules.alias", output_aliases
},
2628 {"modules.alias.bin", output_aliases_bin
},
2629 {"modules.softdep", output_softdeps
},
2630 {"modules.symbols", output_symbols
},
2631 {"modules.symbols.bin", output_symbols_bin
},
2632 {"modules.builtin.bin", output_builtin_bin
},
2633 {"modules.devname", output_devname
},
2636 const char *dname
= depmod
->cfg
->dirname
;
2642 dfd
= open(dname
, O_RDONLY
);
2645 CRIT("Could not open directory %s: %m\n", dname
);
2650 for (itr
= depfiles
; itr
->name
!= NULL
; itr
++) {
2652 char tmp
[NAME_MAX
] = "";
2656 int flags
= O_CREAT
| O_TRUNC
| O_WRONLY
;
2660 snprintf(tmp
, sizeof(tmp
), "%s.tmp", itr
->name
);
2661 fd
= openat(dfd
, tmp
, flags
, mode
);
2663 ERR("openat(%s, %s, %o, %o): %m\n",
2664 dname
, tmp
, flags
, mode
);
2667 fp
= fdopen(fd
, "wb");
2669 ERR("fdopen(%d=%s/%s): %m\n", fd
, dname
, tmp
);
2675 r
= itr
->cb(depmod
, fp
);
2681 if (unlinkat(dfd
, tmp
, 0) != 0)
2682 ERR("unlinkat(%s, %s): %m\n", dname
, tmp
);
2684 unlinkat(dfd
, itr
->name
, 0);
2685 if (renameat(dfd
, tmp
, dfd
, itr
->name
) != 0) {
2687 CRIT("renameat(%s, %s, %s, %s): %m\n",
2688 dname
, tmp
, dname
, itr
->name
);
2699 static void depmod_add_fake_syms(struct depmod
*depmod
)
2701 /* __this_module is magic inserted by kernel loader. */
2702 depmod_symbol_add(depmod
, "__this_module", 0, NULL
);
2703 /* On S390, this is faked up too */
2704 depmod_symbol_add(depmod
, "_GLOBAL_OFFSET_TABLE_", 0, NULL
);
2707 static int depmod_load_symvers(struct depmod
*depmod
, const char *filename
)
2711 unsigned int linenum
= 0;
2714 fp
= fopen(filename
, "r");
2716 DBG("load symvers: %s: %s\n", filename
, strerror(-err
));
2720 /* eg. "0xb352177e\tfind_first_bit\tvmlinux\tEXPORT_SYMBOL" */
2721 while (fgets(line
, sizeof(line
), fp
) != NULL
) {
2722 const char *ver
, *sym
, *where
;
2728 ver
= strtok(line
, " \t");
2729 sym
= strtok(NULL
, " \t");
2730 where
= strtok(NULL
, " \t");
2731 if (!ver
|| !sym
|| !where
)
2734 if (!streq(where
, "vmlinux"))
2737 crc
= strtoull(ver
, &verend
, 16);
2738 if (verend
[0] != '\0') {
2739 ERR("%s:%u Invalid symbol version %s: %m\n",
2740 filename
, linenum
, ver
);
2744 depmod_symbol_add(depmod
, sym
, crc
, NULL
);
2746 depmod_add_fake_syms(depmod
);
2748 DBG("loaded symvers: %s: %s\n", filename
, strerror(-err
));
2754 static int depmod_load_system_map(struct depmod
*depmod
, const char *filename
)
2756 const char ksymstr
[] = "__ksymtab_";
2757 const size_t ksymstr_len
= sizeof(ksymstr
) - 1;
2760 unsigned int linenum
= 0;
2763 fp
= fopen(filename
, "r");
2765 DBG("load System.map: %s: %s\n", filename
, strerror(-err
));
2769 /* eg. c0294200 R __ksymtab_devfs_alloc_devnum */
2770 while (fgets(line
, sizeof(line
), fp
) != NULL
) {
2775 p
= strchr(line
, ' ');
2777 goto invalid_syntax
;
2781 goto invalid_syntax
;
2784 /* Covers gpl-only and normal symbols. */
2785 if (strncmp(p
, ksymstr
, ksymstr_len
) != 0)
2788 end
= strchr(p
, '\n');
2792 depmod_symbol_add(depmod
, p
+ ksymstr_len
, 0, NULL
);
2796 ERR("%s:%u: invalid line: %s\n", filename
, linenum
, line
);
2798 depmod_add_fake_syms(depmod
);
2800 DBG("loaded System.map: %s: %s\n", filename
, strerror(-err
));
2807 static int depfile_up_to_date_dir(DIR *d
, time_t mtime
, size_t baselen
, char *path
)
2810 int err
= 1, dfd
= dirfd(d
);
2812 while ((de
= readdir(d
)) != NULL
) {
2813 const char *name
= de
->d_name
;
2817 if (name
[0] == '.' && (name
[1] == '\0' ||
2818 (name
[1] == '.' && name
[2] == '\0')))
2820 if (streq(name
, "build") || streq(name
, "source"))
2822 namelen
= strlen(name
);
2823 if (baselen
+ namelen
+ 2 >= PATH_MAX
) {
2824 path
[baselen
] = '\0';
2825 ERR("path is too long %s%s %zd\n", path
, name
);
2829 if (fstatat(dfd
, name
, &st
, 0) < 0) {
2830 ERR("fstatat(%d, %s): %m\n", dfd
, name
);
2834 if (S_ISDIR(st
.st_mode
)) {
2837 memcpy(path
+ baselen
, name
, namelen
+ 1);
2838 if (baselen
+ namelen
+ 2 + NAME_MAX
>= PATH_MAX
) {
2839 ERR("directory path is too long %s\n", path
);
2842 fd
= openat(dfd
, name
, O_RDONLY
);
2844 ERR("openat(%d, %s, O_RDONLY): %m\n",
2848 subdir
= fdopendir(fd
);
2849 if (subdir
== NULL
) {
2850 ERR("fdopendir(%d): %m\n", fd
);
2854 path
[baselen
+ namelen
] = '/';
2855 path
[baselen
+ namelen
+ 1] = '\0';
2856 err
= depfile_up_to_date_dir(subdir
, mtime
,
2857 baselen
+ namelen
+ 1,
2860 } else if (S_ISREG(st
.st_mode
)) {
2861 const struct kmod_ext
*eitr
;
2862 uint8_t matches
= 0;
2863 for (eitr
= kmod_exts
; eitr
->ext
!= NULL
; eitr
++) {
2864 if (namelen
<= eitr
->len
)
2866 if (streq(name
+ namelen
- eitr
->len
, eitr
->ext
)) {
2873 memcpy(path
+ baselen
, name
, namelen
+ 1);
2874 err
= st
.st_mtime
<= mtime
;
2876 DBG("%s %"PRIu64
" is newer than %"PRIu64
"\n",
2877 path
, (uint64_t)st
.st_mtime
,
2881 ERR("unsupported file type %s: %o\n",
2882 path
, st
.st_mode
& S_IFMT
);
2887 break; /* outdated! */
2889 path
[baselen
+ namelen
] = '\0';
2890 ERR("failed %s: %s\n", path
, strerror(-err
));
2891 err
= 1; /* ignore errors */
2898 /* uptodate: 1, outdated: 0, errors < 0 */
2899 static int depfile_up_to_date(const char *dirname
)
2901 char path
[PATH_MAX
];
2902 DIR *d
= opendir(dirname
);
2908 ERR("Couldn't open directory %s: %m\n", dirname
);
2912 if (fstatat(dirfd(d
), "modules.dep", &st
, 0) != 0) {
2914 ERR("Couldn't fstatat(%s, modules.dep): %m\n", dirname
);
2919 baselen
= strlen(dirname
);
2920 memcpy(path
, dirname
, baselen
);
2921 path
[baselen
] = '/';
2923 path
[baselen
] = '\0';
2925 err
= depfile_up_to_date_dir(d
, st
.st_mtime
, baselen
, path
);
2930 static int is_version_number(const char *version
)
2932 unsigned int d1
, d2
;
2933 return (sscanf(version
, "%u.%u", &d1
, &d2
) == 2);
2936 int main(int argc
, char *argv
[])
2939 int i
, err
= 0, all
= 0, maybe_all
= 0, n_config_paths
= 0;
2940 const char **config_paths
= NULL
;
2941 const char *root
= "";
2942 const char *system_map
= NULL
;
2943 const char *module_symvers
= NULL
;
2944 const char *null_kmod_config
= NULL
;
2946 struct kmod_ctx
*ctx
= NULL
;
2948 struct depmod depmod
;
2950 memset(&cfg
, 0, sizeof(cfg
));
2951 memset(&depmod
, 0, sizeof(depmod
));
2955 c
= getopt_long(argc
, argv
, cmdopts_s
, cmdopts
, &idx
);
2969 size_t bytes
= sizeof(char *) * (n_config_paths
+ 2);
2970 void *tmp
= realloc(config_paths
, bytes
);
2972 fputs("Error: out-of-memory\n", stderr
);
2973 goto cmdline_failed
;
2976 config_paths
[n_config_paths
] = optarg
;
2978 config_paths
[n_config_paths
] = NULL
;
2982 module_symvers
= optarg
;
2983 cfg
.check_symvers
= 1;
2986 system_map
= optarg
;
2989 cfg
.print_unknown
= 1;
2998 if (optarg
[1] != '\0') {
2999 CRIT("-P only takes a single char\n");
3000 goto cmdline_failed
;
3002 cfg
.sym_prefix
= optarg
[0];
3013 "ignored deprecated option --%s\n",
3017 "ignored deprecated option -%c\n", c
);
3023 return EXIT_SUCCESS
;
3025 puts(PACKAGE
" version " VERSION
);
3027 return EXIT_SUCCESS
;
3029 goto cmdline_failed
;
3032 "Error: unexpected getopt_long() value '%c'.\n",
3034 goto cmdline_failed
;
3038 if (optind
< argc
&& is_version_number(argv
[optind
])) {
3039 cfg
.kversion
= argv
[optind
];
3042 if (uname(&un
) < 0) {
3043 CRIT("uname() failed: %s\n", strerror(errno
));
3044 goto cmdline_failed
;
3046 cfg
.kversion
= un
.release
;
3049 cfg
.dirnamelen
= snprintf(cfg
.dirname
, PATH_MAX
,
3050 "%s" ROOTPREFIX
"/lib/modules/%s",
3051 root
, cfg
.kversion
);
3059 /* ignore up-to-date errors (< 0) */
3060 if (depfile_up_to_date(cfg
.dirname
) == 1) {
3061 DBG("%s/modules.dep is up to date!\n", cfg
.dirname
);
3064 DBG("%s/modules.dep is outdated, do -a\n", cfg
.dirname
);
3068 ctx
= kmod_new(cfg
.dirname
, &null_kmod_config
);
3070 CRIT("kmod_new(\"%s\", {NULL}) failed: %m\n", cfg
.dirname
);
3071 goto cmdline_failed
;
3073 kmod_set_log_priority(ctx
, verbose
);
3075 err
= depmod_init(&depmod
, &cfg
, ctx
);
3077 CRIT("depmod_init: %s\n", strerror(-err
));
3078 goto depmod_init_failed
;
3080 ctx
= NULL
; /* owned by depmod */
3082 if (module_symvers
!= NULL
) {
3083 err
= depmod_load_symvers(&depmod
, module_symvers
);
3085 CRIT("Could not load %s: %s\n", module_symvers
,
3087 goto cmdline_failed
;
3089 } else if (system_map
!= NULL
) {
3090 err
= depmod_load_system_map(&depmod
, system_map
);
3092 CRIT("Could not load %s: %s\n", module_symvers
,
3094 goto cmdline_failed
;
3096 } else if (cfg
.print_unknown
) {
3097 WRN("-e needs -E or -F\n");
3098 cfg
.print_unknown
= 0;
3102 err
= cfg_load(&cfg
, config_paths
);
3104 CRIT("Could not load configuration files\n");
3105 goto cmdline_modules_failed
;
3107 err
= depmod_modules_search(&depmod
);
3109 CRIT("Could search modules: %s\n", strerror(-err
));
3110 goto cmdline_modules_failed
;
3113 for (i
= optind
; i
< argc
; i
++) {
3114 const char *path
= argv
[i
];
3115 struct kmod_module
*mod
;
3117 if (path
[0] != '/') {
3118 CRIT("%s: not absolute path.", path
);
3119 goto cmdline_modules_failed
;
3122 err
= kmod_module_new_from_path(depmod
.ctx
, path
, &mod
);
3124 CRIT("Could not create module %s: %s\n",
3125 path
, strerror(-err
));
3126 goto cmdline_modules_failed
;
3129 err
= depmod_module_add(&depmod
, mod
);
3131 CRIT("Could not add module %s: %s\n",
3132 path
, strerror(-err
));
3133 kmod_module_unref(mod
);
3134 goto cmdline_modules_failed
;
3139 depmod_modules_sort(&depmod
);
3140 err
= depmod_load(&depmod
);
3142 goto cmdline_modules_failed
;
3144 err
= depmod_output(&depmod
, out
);
3147 depmod_shutdown(&depmod
);
3150 return err
>= 0 ? EXIT_SUCCESS
: EXIT_FAILURE
;
3152 cmdline_modules_failed
:
3153 depmod_shutdown(&depmod
);
3160 return EXIT_FAILURE
;