Support /usr/local for configuration files
[platform/upstream/kmod.git] / tools / depmod.c
1 /*
2  * kmod-depmod - calculate modules.dep  using libkmod.
3  *
4  * Copyright (C) 2011-2013  ProFUSION embedded systems
5  *
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.
10  *
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.
15  *
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/>.
18  */
19
20 #include <assert.h>
21 #include <ctype.h>
22 #include <dirent.h>
23 #include <errno.h>
24 #include <getopt.h>
25 #include <limits.h>
26 #include <regex.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <unistd.h>
31 #include <sys/stat.h>
32 #include <sys/time.h>
33 #include <sys/utsname.h>
34
35 #include <shared/array.h>
36 #include <shared/hash.h>
37 #include <shared/macro.h>
38 #include <shared/util.h>
39 #include <shared/scratchbuf.h>
40
41 #include <libkmod/libkmod-internal.h>
42
43 #undef ERR
44 #undef DBG
45
46 #include "kmod.h"
47
48 #define DEFAULT_VERBOSE LOG_WARNING
49 static int verbose = DEFAULT_VERBOSE;
50
51 static const char CFG_BUILTIN_KEY[] = "built-in";
52 static const char CFG_EXTERNAL_KEY[] = "external";
53 static const char *default_cfg_paths[] = {
54         SYSCONFDIR "/depmod.d",
55         "/run/depmod.d",
56         "/usr/local/lib/depmod.d",
57         "/lib/depmod.d",
58         NULL
59 };
60
61 static const char cmdopts_s[] = "aAb:C:E:F:euqrvnP:wmVh";
62 static const struct option cmdopts[] = {
63         { "all", no_argument, 0, 'a' },
64         { "quick", no_argument, 0, 'A' },
65         { "basedir", required_argument, 0, 'b' },
66         { "config", required_argument, 0, 'C' },
67         { "symvers", required_argument, 0, 'E' },
68         { "filesyms", required_argument, 0, 'F' },
69         { "errsyms", no_argument, 0, 'e' },
70         { "unresolved-error", no_argument, 0, 'u' }, /* deprecated */
71         { "quiet", no_argument, 0, 'q' }, /* deprecated */
72         { "root", no_argument, 0, 'r' }, /* deprecated */
73         { "verbose", no_argument, 0, 'v' },
74         { "show", no_argument, 0, 'n' },
75         { "dry-run", no_argument, 0, 'n' },
76         { "symbol-prefix", required_argument, 0, 'P' },
77         { "warn", no_argument, 0, 'w' },
78         { "map", no_argument, 0, 'm' }, /* deprecated */
79         { "version", no_argument, 0, 'V' },
80         { "help", no_argument, 0, 'h' },
81         { }
82 };
83
84 static void help(void)
85 {
86         printf("Usage:\n"
87                 "\t%s -[aA] [options] [forced_version]\n"
88                 "\n"
89                 "If no arguments (except options) are given, \"depmod -a\" is assumed\n"
90                 "\n"
91                 "depmod will output a dependency list suitable for the modprobe utility.\n"
92                 "\n"
93                 "Options:\n"
94                 "\t-a, --all            Probe all modules\n"
95                 "\t-A, --quick          Only does the work if there's a new module\n"
96                 "\t-e, --errsyms        Report not supplied symbols\n"
97                 "\t-n, --show           Write the dependency file on stdout only\n"
98                 "\t-P, --symbol-prefix  Architecture symbol prefix\n"
99                 "\t-C, --config=PATH    Read configuration from PATH\n"
100                 "\t-v, --verbose        Enable verbose mode\n"
101                 "\t-w, --warn           Warn on duplicates\n"
102                 "\t-V, --version        show version\n"
103                 "\t-h, --help           show this help\n"
104                 "\n"
105                 "The following options are useful for people managing distributions:\n"
106                 "\t-b, --basedir=DIR    Use an image of a module tree.\n"
107                 "\t-F, --filesyms=FILE  Use the file instead of the\n"
108                 "\t                     current kernel symbols.\n"
109                 "\t-E, --symvers=FILE   Use Module.symvers file to check\n"
110                 "\t                     symbol versions.\n",
111                 program_invocation_short_name);
112 }
113
114 _printf_format_(1, 2)
115 static inline void _show(const char *fmt, ...)
116 {
117         va_list args;
118
119         if (verbose <= DEFAULT_VERBOSE)
120                 return;
121
122         va_start(args, fmt);
123         vfprintf(stdout, fmt, args);
124         fflush(stdout);
125         va_end(args);
126 }
127 #define SHOW(...) _show(__VA_ARGS__)
128
129
130 /* binary index write *************************************************/
131 #include <arpa/inet.h>
132 /* BEGIN: code from module-init-tools/index.c just modified to compile here.
133  *
134  * Original copyright:
135  *   index.c: module index file shared functions for modprobe and depmod
136  *   Copyright (C) 2008  Alan Jenkins <alan-jenkins@tuffmail.co.uk>.
137  *
138  *   These programs are free software; you can redistribute it and/or modify
139  *   it under the terms of the GNU General Public License as published by
140  *   the Free Software Foundation; either version 2 of the License, or
141  *   (at your option) any later version.
142  *
143  *   This program is distributed in the hope that it will be useful,
144  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
145  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
146  *   GNU General Public License for more details.
147  *
148  *   You should have received a copy of the GNU General Public License
149  *   along with these programs.  If not, see <http://www.gnu.org/licenses/>.
150  */
151
152 /* see documentation in libkmod/libkmod-index.c */
153
154 #define INDEX_MAGIC 0xB007F457
155 #define INDEX_VERSION_MAJOR 0x0002
156 #define INDEX_VERSION_MINOR 0x0001
157 #define INDEX_VERSION ((INDEX_VERSION_MAJOR<<16)|INDEX_VERSION_MINOR)
158 #define INDEX_CHILDMAX 128
159
160 struct index_value {
161         struct index_value *next;
162         unsigned int priority;
163         char value[0];
164 };
165
166 /* In-memory index (depmod only) */
167 struct index_node {
168         char *prefix;           /* path compression */
169         struct index_value *values;
170         unsigned char first;    /* range of child nodes */
171         unsigned char last;
172         struct index_node *children[INDEX_CHILDMAX]; /* indexed by character */
173 };
174
175
176 /* Format of node offsets within index file */
177 enum node_offset {
178         INDEX_NODE_FLAGS    = 0xF0000000, /* Flags in high nibble */
179         INDEX_NODE_PREFIX   = 0x80000000,
180         INDEX_NODE_VALUES = 0x40000000,
181         INDEX_NODE_CHILDS   = 0x20000000,
182
183         INDEX_NODE_MASK     = 0x0FFFFFFF, /* Offset value */
184 };
185
186 static struct index_node *index_create(void)
187 {
188         struct index_node *node;
189
190         node = NOFAIL(calloc(sizeof(struct index_node), 1));
191         node->prefix = NOFAIL(strdup(""));
192         node->first = INDEX_CHILDMAX;
193
194         return node;
195 }
196
197 static void index_values_free(struct index_value *values)
198 {
199         while (values) {
200                 struct index_value *value = values;
201
202                 values = value->next;
203                 free(value);
204         }
205 }
206
207 static void index_destroy(struct index_node *node)
208 {
209         int c;
210
211         for (c = node->first; c <= node->last; c++) {
212                 struct index_node *child = node->children[c];
213
214                 if (child)
215                         index_destroy(child);
216         }
217         index_values_free(node->values);
218         free(node->prefix);
219         free(node);
220 }
221
222 static void index__checkstring(const char *str)
223 {
224         int i;
225
226         for (i = 0; str[i]; i++) {
227                 int ch = str[i];
228
229                 if (ch >= INDEX_CHILDMAX)
230                         CRIT("Module index: bad character '%c'=0x%x - only 7-bit ASCII is supported:"
231                               "\n%s\n", (char) ch, (int) ch, str);
232         }
233 }
234
235 static int index_add_value(struct index_value **values,
236                                 const char *value, unsigned int priority)
237 {
238         struct index_value *v;
239         int duplicate = 0;
240         int len;
241
242         /* report the presence of duplicate values */
243         for (v = *values; v; v = v->next) {
244                 if (streq(v->value, value))
245                         duplicate = 1;
246         }
247
248         /* find position to insert value */
249         while (*values && (*values)->priority < priority)
250                 values = &(*values)->next;
251
252         len = strlen(value);
253         v = NOFAIL(calloc(sizeof(struct index_value) + len + 1, 1));
254         v->next = *values;
255         v->priority = priority;
256         memcpy(v->value, value, len + 1);
257         *values = v;
258
259         return duplicate;
260 }
261
262 static int index_insert(struct index_node *node, const char *key,
263                         const char *value, unsigned int priority)
264 {
265         int i = 0; /* index within str */
266         int ch;
267
268         index__checkstring(key);
269         index__checkstring(value);
270
271         while(1) {
272                 int j; /* index within node->prefix */
273
274                 /* Ensure node->prefix is a prefix of &str[i].
275                    If it is not already, then we must split node. */
276                 for (j = 0; node->prefix[j]; j++) {
277                         ch = node->prefix[j];
278
279                         if (ch != key[i+j]) {
280                                 char *prefix = node->prefix;
281                                 struct index_node *n;
282
283                                 /* New child is copy of node with prefix[j+1..N] */
284                                 n = NOFAIL(calloc(sizeof(struct index_node), 1));
285                                 memcpy(n, node, sizeof(struct index_node));
286                                 n->prefix = NOFAIL(strdup(&prefix[j+1]));
287
288                                 /* Parent has prefix[0..j], child at prefix[j] */
289                                 memset(node, 0, sizeof(struct index_node));
290                                 prefix[j] = '\0';
291                                 node->prefix = prefix;
292                                 node->first = ch;
293                                 node->last = ch;
294                                 node->children[ch] = n;
295
296                                 break;
297                         }
298                 }
299                 /* j is now length of node->prefix */
300                 i += j;
301
302                 ch = key[i];
303                 if(ch == '\0')
304                         return index_add_value(&node->values, value, priority);
305
306                 if (!node->children[ch]) {
307                         struct index_node *child;
308
309                         if (ch < node->first)
310                                 node->first = ch;
311                         if (ch > node->last)
312                                 node->last = ch;
313                         node->children[ch] = NOFAIL(calloc(sizeof(struct index_node), 1));
314
315                         child = node->children[ch];
316                         child->prefix = NOFAIL(strdup(&key[i+1]));
317                         child->first = INDEX_CHILDMAX;
318                         index_add_value(&child->values, value, priority);
319
320                         return 0;
321                 }
322
323                 /* Descend into child node and continue */
324                 node = node->children[ch];
325                 i++;
326         }
327 }
328
329 static int index__haschildren(const struct index_node *node)
330 {
331         return node->first < INDEX_CHILDMAX;
332 }
333
334 /* Recursive post-order traversal
335
336    Pre-order would make for better read-side buffering / readahead / caching.
337    (post-order means you go backwards in the file as you descend the tree).
338    However, index reading is already fast enough.
339    Pre-order is simpler for writing, and depmod is already slow.
340  */
341 static uint32_t index_write__node(const struct index_node *node, FILE *out)
342 {
343         uint32_t *child_offs = NULL;
344         int child_count = 0;
345         long offset;
346
347         if (!node)
348                 return 0;
349
350         /* Write children and save their offsets */
351         if (index__haschildren(node)) {
352                 const struct index_node *child;
353                 int i;
354
355                 child_count = node->last - node->first + 1;
356                 child_offs = NOFAIL(malloc(child_count * sizeof(uint32_t)));
357
358                 for (i = 0; i < child_count; i++) {
359                         child = node->children[node->first + i];
360                         child_offs[i] = htonl(index_write__node(child, out));
361                 }
362         }
363
364         /* Now write this node */
365         offset = ftell(out);
366
367         if (node->prefix[0]) {
368                 fputs(node->prefix, out);
369                 fputc('\0', out);
370                 offset |= INDEX_NODE_PREFIX;
371         }
372
373         if (child_count) {
374                 fputc(node->first, out);
375                 fputc(node->last, out);
376                 fwrite(child_offs, sizeof(uint32_t), child_count, out);
377                 offset |= INDEX_NODE_CHILDS;
378         }
379
380         free(child_offs);
381
382         if (node->values) {
383                 const struct index_value *v;
384                 unsigned int value_count;
385                 uint32_t u;
386
387                 value_count = 0;
388                 for (v = node->values; v != NULL; v = v->next)
389                         value_count++;
390                 u = htonl(value_count);
391                 fwrite(&u, sizeof(u), 1, out);
392
393                 for (v = node->values; v != NULL; v = v->next) {
394                         u = htonl(v->priority);
395                         fwrite(&u, sizeof(u), 1, out);
396                         fputs(v->value, out);
397                         fputc('\0', out);
398                 }
399                 offset |= INDEX_NODE_VALUES;
400         }
401
402         return offset;
403 }
404
405 static void index_write(const struct index_node *node, FILE *out)
406 {
407         long initial_offset, final_offset;
408         uint32_t u;
409
410         u = htonl(INDEX_MAGIC);
411         fwrite(&u, sizeof(u), 1, out);
412         u = htonl(INDEX_VERSION);
413         fwrite(&u, sizeof(u), 1, out);
414
415         /* Second word is reserved for the offset of the root node */
416         initial_offset = ftell(out);
417         assert(initial_offset >= 0);
418         u = 0;
419         fwrite(&u, sizeof(uint32_t), 1, out);
420
421         /* Dump trie */
422         u = htonl(index_write__node(node, out));
423
424         /* Update first word */
425         final_offset = ftell(out);
426         assert(final_offset >= 0);
427         (void)fseek(out, initial_offset, SEEK_SET);
428         fwrite(&u, sizeof(uint32_t), 1, out);
429         (void)fseek(out, final_offset, SEEK_SET);
430 }
431
432 /* END: code from module-init-tools/index.c just modified to compile here.
433  */
434
435 /* configuration parsing **********************************************/
436 struct cfg_override {
437         struct cfg_override *next;
438         size_t len;
439         char path[];
440 };
441
442 enum search_type {
443         SEARCH_PATH,
444         SEARCH_BUILTIN,
445         SEARCH_EXTERNAL
446 };
447
448 struct cfg_search {
449         struct cfg_search *next;
450         enum search_type type;
451         size_t len;
452         char path[];
453 };
454
455 struct cfg_external {
456         struct cfg_external *next;
457         size_t len;
458         char path[];
459 };
460
461 struct cfg {
462         const char *kversion;
463         char dirname[PATH_MAX];
464         size_t dirnamelen;
465         char sym_prefix;
466         uint8_t check_symvers;
467         uint8_t print_unknown;
468         uint8_t warn_dups;
469         struct cfg_override *overrides;
470         struct cfg_search *searches;
471         struct cfg_external *externals;
472 };
473
474 static enum search_type cfg_define_search_type(const char *path)
475 {
476         if (streq(path, CFG_BUILTIN_KEY))
477                 return SEARCH_BUILTIN;
478         if (streq(path, CFG_EXTERNAL_KEY))
479                 return SEARCH_EXTERNAL;
480         return SEARCH_PATH;
481 }
482
483 static int cfg_search_add(struct cfg *cfg, const char *path)
484 {
485         struct cfg_search *s;
486         size_t len;
487         enum search_type type;
488
489         type = cfg_define_search_type(path);
490
491         if (type != SEARCH_PATH)
492                 len = 0;
493         else
494                 len = strlen(path) + 1;
495
496         s = malloc(sizeof(struct cfg_search) + len);
497         if (s == NULL) {
498                 ERR("search add: out of memory\n");
499                 return -ENOMEM;
500         }
501         s->type = type;
502         if (type != SEARCH_PATH)
503                 s->len = 0;
504         else {
505                 s->len = len - 1;
506                 memcpy(s->path, path, len);
507         }
508
509         DBG("search add: %s, search type=%hhu\n", path, type);
510
511         s->next = cfg->searches;
512         cfg->searches = s;
513         return 0;
514 }
515
516 static void cfg_search_free(struct cfg_search *s)
517 {
518         free(s);
519 }
520
521 static int cfg_override_add(struct cfg *cfg, const char *modname, const char *subdir)
522 {
523         struct cfg_override *o;
524         size_t modnamelen = strlen(modname);
525         size_t subdirlen = strlen(subdir);
526         size_t i;
527
528         o = malloc(sizeof(struct cfg_override) + subdirlen + 1
529                    + modnamelen + 1);
530         if (o == NULL) {
531                 ERR("override add: out of memory\n");
532                 return -ENOMEM;
533         }
534         memcpy(o->path, subdir, subdirlen);
535         i = subdirlen;
536         o->path[i] = '/';
537         i++;
538
539         memcpy(o->path + i, modname, modnamelen);
540         i += modnamelen;
541         o->path[i] = '\0'; /* no extension, so we can match .ko/.ko.gz */
542
543         o->len = i;
544
545         DBG("override add: %s\n", o->path);
546
547         o->next = cfg->overrides;
548         cfg->overrides = o;
549         return 0;
550 }
551
552 static void cfg_override_free(struct cfg_override *o)
553 {
554         free(o);
555 }
556
557 static int cfg_external_add(struct cfg *cfg, const char *path)
558 {
559         struct cfg_external *ext;
560         size_t len = strlen(path);
561
562         ext = malloc(sizeof(struct cfg_external) + len + 1);
563         if (ext == NULL) {
564                 ERR("external add: out of memory\n");
565                 return -ENOMEM;
566         }
567
568         strcpy(ext->path, path);
569         ext->len = len;
570
571         DBG("external add: %s\n", ext->path);
572
573         ext->next = cfg->externals;
574         cfg->externals = ext;
575         return 0;
576 }
577
578 static void cfg_external_free(struct cfg_external *ext)
579 {
580         free(ext);
581 }
582
583 static int cfg_kernel_matches(const struct cfg *cfg, const char *pattern)
584 {
585         regex_t re;
586         int status;
587
588         /* old style */
589         if (streq(pattern, "*"))
590                 return 1;
591
592         if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB) != 0)
593                 return 0;
594
595         status = regexec(&re, cfg->kversion, 0, NULL, 0);
596         regfree(&re);
597
598         return status == 0;
599 }
600
601 static int cfg_file_parse(struct cfg *cfg, const char *filename)
602 {
603         char *line;
604         FILE *fp;
605         unsigned int linenum = 0;
606         int err;
607
608         fp = fopen(filename, "r");
609         if (fp == NULL) {
610                 err = -errno;
611                 ERR("file parse %s: %m\n", filename);
612                 return err;
613         }
614
615         while ((line = freadline_wrapped(fp, &linenum)) != NULL) {
616                 char *cmd, *saveptr;
617
618                 if (line[0] == '\0' || line[0] == '#')
619                         goto done_next;
620
621                 cmd = strtok_r(line, "\t ", &saveptr);
622                 if (cmd == NULL)
623                         goto done_next;
624
625                 if (streq(cmd, "search")) {
626                         const char *sp;
627                         while ((sp = strtok_r(NULL, "\t ", &saveptr)) != NULL) {
628                                 cfg_search_add(cfg, sp);
629                         }
630                 } else if (streq(cmd, "override")) {
631                         const char *modname = strtok_r(NULL, "\t ", &saveptr);
632                         const char *version = strtok_r(NULL, "\t ", &saveptr);
633                         const char *subdir = strtok_r(NULL, "\t ", &saveptr);
634
635                         if (modname == NULL || version == NULL ||
636                                         subdir == NULL)
637                                 goto syntax_error;
638
639                         if (!cfg_kernel_matches(cfg, version)) {
640                                 INF("%s:%u: override kernel did not match %s\n",
641                                     filename, linenum, version);
642                                 goto done_next;
643                         }
644
645                         cfg_override_add(cfg, modname, subdir);
646                 } else if (streq(cmd, "external")) {
647                         const char *version = strtok_r(NULL, "\t ", &saveptr);
648                         const char *dir = strtok_r(NULL, "\t ", &saveptr);
649
650                         if (version == NULL || dir == NULL)
651                                 goto syntax_error;
652
653                         if (!cfg_kernel_matches(cfg, version)) {
654                                 INF("%s:%u: external directory did not match %s\n",
655                                     filename, linenum, version);
656                                 goto done_next;
657                         }
658
659                         cfg_external_add(cfg, dir);
660                 } else if (streq(cmd, "include")
661                                 || streq(cmd, "make_map_files")) {
662                         INF("%s:%u: command %s not implemented yet\n",
663                             filename, linenum, cmd);
664                 } else {
665 syntax_error:
666                         ERR("%s:%u: ignoring bad line starting with '%s'\n",
667                             filename, linenum, cmd);
668                 }
669
670 done_next:
671                 free(line);
672         }
673
674         fclose(fp);
675
676         return 0;
677 }
678
679 static int cfg_files_filter_out(DIR *d, const char *dir, const char *name)
680 {
681         size_t len = strlen(name);
682         struct stat st;
683
684         if (name[0] == '.')
685                 return 1;
686
687         if (len < 6 || !streq(name + len - 5, ".conf")) {
688                 INF("All cfg files need .conf: %s/%s\n", dir, name);
689                 return 1;
690         }
691
692         fstatat(dirfd(d), name, &st, 0);
693         if (S_ISDIR(st.st_mode)) {
694                 ERR("Directories inside directories are not supported: %s/%s\n",
695                     dir, name);
696                 return 1;
697         }
698
699         return 0;
700 }
701
702 struct cfg_file {
703         size_t dirlen;
704         size_t namelen;
705         const char *name;
706         char path[];
707 };
708
709 static void cfg_file_free(struct cfg_file *f)
710 {
711         free(f);
712 }
713
714 static int cfg_files_insert_sorted(struct cfg_file ***p_files, size_t *p_n_files,
715                                         const char *dir, const char *name)
716 {
717         struct cfg_file **files, *f;
718         size_t i, n_files, namelen, dirlen;
719         void *tmp;
720
721         dirlen = strlen(dir);
722         if (name != NULL)
723                 namelen = strlen(name);
724         else {
725                 name = basename(dir);
726                 namelen = strlen(name);
727                 dirlen -= namelen + 1;
728         }
729
730         n_files = *p_n_files;
731         files = *p_files;
732         for (i = 0; i < n_files; i++) {
733                 int cmp = strcmp(name, files[i]->name);
734                 if (cmp == 0) {
735                         DBG("Ignoring duplicate config file: %.*s/%s\n",
736                             (int)dirlen, dir, name);
737                         return -EEXIST;
738                 } else if (cmp < 0)
739                         break;
740         }
741
742         f = malloc(sizeof(struct cfg_file) + dirlen + namelen + 2);
743         if (f == NULL) {
744                 ERR("files insert sorted: out of memory\n");
745                 return -ENOMEM;
746         }
747
748         tmp = realloc(files, sizeof(struct cfg_file *) * (n_files + 1));
749         if (tmp == NULL) {
750                 ERR("files insert sorted: out of memory\n");
751                 free(f);
752                 return -ENOMEM;
753         }
754         *p_files = files = tmp;
755
756         if (i < n_files) {
757                 memmove(files + i + 1, files + i,
758                         sizeof(struct cfg_file *) * (n_files - i));
759         }
760         files[i] = f;
761
762         f->dirlen = dirlen;
763         f->namelen = namelen;
764         f->name = f->path + dirlen + 1;
765         memcpy(f->path, dir, dirlen);
766         f->path[dirlen] = '/';
767         memcpy(f->path + dirlen + 1, name, namelen);
768         f->path[dirlen + 1 + namelen] = '\0';
769
770         *p_n_files = n_files + 1;
771         return 0;
772 }
773
774 /*
775  * Insert configuration files ignoring duplicates
776  */
777 static int cfg_files_list(struct cfg_file ***p_files, size_t *p_n_files,
778                                 const char *path)
779 {
780         struct dirent *dent;
781         DIR *d;
782         int err = 0;
783         struct stat st;
784
785         if (stat(path, &st) != 0) {
786                 err = -errno;
787                 DBG("could not stat '%s': %m\n", path);
788                 return err;
789         }
790
791         if (!S_ISDIR(st.st_mode)) {
792                 cfg_files_insert_sorted(p_files, p_n_files, path, NULL);
793                 return 0;
794         }
795
796         d = opendir(path);
797         if (d == NULL) {
798                 ERR("files list %s: %m\n", path);
799                 return -EINVAL;
800         }
801
802         for (dent = readdir(d); dent != NULL; dent = readdir(d)) {
803                 if (cfg_files_filter_out(d, path, dent->d_name))
804                         continue;
805
806                 cfg_files_insert_sorted(p_files, p_n_files, path, dent->d_name);
807         }
808
809         closedir(d);
810         DBG("parsed configuration files from %s\n", path);
811         return err;
812 }
813
814 static int cfg_load(struct cfg *cfg, const char * const *cfg_paths)
815 {
816         size_t i, n_files = 0;
817         struct cfg_file **files = NULL;
818
819         if (cfg_paths == NULL)
820                 cfg_paths = default_cfg_paths;
821
822         for (i = 0; cfg_paths[i] != NULL; i++)
823                 cfg_files_list(&files, &n_files, cfg_paths[i]);
824
825         for (i = 0; i < n_files; i++) {
826                 struct cfg_file *f = files[i];
827                 cfg_file_parse(cfg, f->path);
828                 cfg_file_free(f);
829         }
830         free(files);
831
832         /* For backward compatibility add "updates" to the head of the search
833          * list here. But only if there was no "search" option specified.
834          */
835         if (cfg->searches == NULL)
836                 cfg_search_add(cfg, "updates");
837
838         return 0;
839 }
840
841 static void cfg_free(struct cfg *cfg)
842 {
843         while (cfg->overrides) {
844                 struct cfg_override *tmp = cfg->overrides;
845                 cfg->overrides = cfg->overrides->next;
846                 cfg_override_free(tmp);
847         }
848
849         while (cfg->searches) {
850                 struct cfg_search *tmp = cfg->searches;
851                 cfg->searches = cfg->searches->next;
852                 cfg_search_free(tmp);
853         }
854
855         while (cfg->externals) {
856                 struct cfg_external *tmp = cfg->externals;
857                 cfg->externals = cfg->externals->next;
858                 cfg_external_free(tmp);
859         }
860 }
861
862
863 /* depmod calculations ***********************************************/
864 struct vertex;
865 struct mod {
866         struct kmod_module *kmod;
867         char *path;
868         const char *relpath; /* path relative to '$ROOT/lib/modules/$VER/' */
869         char *uncrelpath; /* same as relpath but ending in .ko */
870         struct kmod_list *info_list;
871         struct kmod_list *dep_sym_list;
872         struct array deps; /* struct symbol */
873         size_t baselen; /* points to start of basename/filename */
874         size_t modnamesz;
875         int sort_idx; /* sort index using modules.order */
876         int dep_sort_idx; /* topological sort index */
877         uint16_t idx; /* index in depmod->modules.array */
878         uint16_t users; /* how many modules depend on this one */
879         bool visited; /* helper field to report cycles */
880         struct vertex *vertex; /* helper field to report cycles */
881         char modname[];
882 };
883
884 struct symbol {
885         struct mod *owner;
886         uint64_t crc;
887         char name[];
888 };
889
890 struct depmod {
891         const struct cfg *cfg;
892         struct kmod_ctx *ctx;
893         struct array modules;
894         struct hash *modules_by_uncrelpath;
895         struct hash *modules_by_name;
896         struct hash *symbols;
897 };
898
899 static void mod_free(struct mod *mod)
900 {
901         DBG("free %p kmod=%p, path=%s\n", mod, mod->kmod, mod->path);
902         array_free_array(&mod->deps);
903         kmod_module_unref(mod->kmod);
904         kmod_module_info_free_list(mod->info_list);
905         kmod_module_dependency_symbols_free_list(mod->dep_sym_list);
906         free(mod->uncrelpath);
907         free(mod->path);
908         free(mod);
909 }
910
911 static int mod_add_dependency(struct mod *mod, struct symbol *sym)
912 {
913         int err;
914
915         DBG("%s depends on %s %s\n", mod->path, sym->name,
916             sym->owner != NULL ? sym->owner->path : "(unknown)");
917
918         if (sym->owner == NULL)
919                 return 0;
920
921         err = array_append_unique(&mod->deps, sym->owner);
922         if (err == -EEXIST)
923                 return 0;
924         if (err < 0)
925                 return err;
926
927         sym->owner->users++;
928         SHOW("%s needs \"%s\": %s\n", mod->path, sym->name, sym->owner->path);
929         return 0;
930 }
931
932 static void symbol_free(struct symbol *sym)
933 {
934         DBG("free %p sym=%s, owner=%p %s\n", sym, sym->name, sym->owner,
935             sym->owner != NULL ? sym->owner->path : "");
936         free(sym);
937 }
938
939 static int depmod_init(struct depmod *depmod, struct cfg *cfg,
940                                                         struct kmod_ctx *ctx)
941 {
942         int err = 0;
943
944         depmod->cfg = cfg;
945         depmod->ctx = ctx;
946
947         array_init(&depmod->modules, 128);
948
949         depmod->modules_by_uncrelpath = hash_new(512, NULL);
950         if (depmod->modules_by_uncrelpath == NULL) {
951                 err = -errno;
952                 goto modules_by_uncrelpath_failed;
953         }
954
955         depmod->modules_by_name = hash_new(512, NULL);
956         if (depmod->modules_by_name == NULL) {
957                 err = -errno;
958                 goto modules_by_name_failed;
959         }
960
961         depmod->symbols = hash_new(2048, (void (*)(void *))symbol_free);
962         if (depmod->symbols == NULL) {
963                 err = -errno;
964                 goto symbols_failed;
965         }
966
967         return 0;
968
969 symbols_failed:
970         hash_free(depmod->modules_by_name);
971 modules_by_name_failed:
972         hash_free(depmod->modules_by_uncrelpath);
973 modules_by_uncrelpath_failed:
974         return err;
975 }
976
977 static void depmod_shutdown(struct depmod *depmod)
978 {
979         size_t i;
980
981         hash_free(depmod->symbols);
982
983         hash_free(depmod->modules_by_uncrelpath);
984
985         hash_free(depmod->modules_by_name);
986
987         for (i = 0; i < depmod->modules.count; i++)
988                 mod_free(depmod->modules.array[i]);
989         array_free_array(&depmod->modules);
990
991         kmod_unref(depmod->ctx);
992 }
993
994 static int depmod_module_add(struct depmod *depmod, struct kmod_module *kmod)
995 {
996         const struct cfg *cfg = depmod->cfg;
997         const char *modname, *lastslash;
998         size_t modnamesz;
999         struct mod *mod;
1000         int err;
1001
1002         modname = kmod_module_get_name(kmod);
1003         modnamesz = strlen(modname) + 1;
1004
1005         mod = calloc(1, sizeof(struct mod) + modnamesz);
1006         if (mod == NULL)
1007                 return -ENOMEM;
1008         mod->kmod = kmod;
1009         mod->sort_idx = depmod->modules.count + 1;
1010         mod->dep_sort_idx = INT32_MAX;
1011         memcpy(mod->modname, modname, modnamesz);
1012         mod->modnamesz = modnamesz;
1013
1014         array_init(&mod->deps, 4);
1015
1016         mod->path = strdup(kmod_module_get_path(kmod));
1017         lastslash = strrchr(mod->path, '/');
1018         mod->baselen = lastslash - mod->path;
1019         if (strncmp(mod->path, cfg->dirname, cfg->dirnamelen) == 0 &&
1020                         mod->path[cfg->dirnamelen] == '/')
1021                 mod->relpath = mod->path + cfg->dirnamelen + 1;
1022         else
1023                 mod->relpath = NULL;
1024
1025         err = hash_add_unique(depmod->modules_by_name, mod->modname, mod);
1026         if (err < 0) {
1027                 ERR("hash_add_unique %s: %s\n", mod->modname, strerror(-err));
1028                 goto fail;
1029         }
1030
1031         if (mod->relpath != NULL) {
1032                 size_t uncrelpathlen = lastslash - mod->relpath + modnamesz
1033                                        + strlen(KMOD_EXTENSION_UNCOMPRESSED);
1034                 mod->uncrelpath = memdup(mod->relpath, uncrelpathlen + 1);
1035                 mod->uncrelpath[uncrelpathlen] = '\0';
1036                 err = hash_add_unique(depmod->modules_by_uncrelpath,
1037                                       mod->uncrelpath, mod);
1038                 if (err < 0) {
1039                         ERR("hash_add_unique %s: %s\n",
1040                             mod->uncrelpath, strerror(-err));
1041                         hash_del(depmod->modules_by_name, mod->modname);
1042                         goto fail;
1043                 }
1044         }
1045
1046         DBG("add %p kmod=%p, path=%s\n", mod, kmod, mod->path);
1047
1048         return 0;
1049
1050 fail:
1051         free(mod->uncrelpath);
1052         free(mod);
1053         return err;
1054 }
1055
1056 static int depmod_module_del(struct depmod *depmod, struct mod *mod)
1057 {
1058         DBG("del %p kmod=%p, path=%s\n", mod, mod->kmod, mod->path);
1059
1060         if (mod->uncrelpath != NULL)
1061                 hash_del(depmod->modules_by_uncrelpath, mod->uncrelpath);
1062
1063         hash_del(depmod->modules_by_name, mod->modname);
1064
1065         mod_free(mod);
1066         return 0;
1067 }
1068
1069 static const char *search_to_string(const struct cfg_search *s)
1070 {
1071         switch(s->type) {
1072         case SEARCH_EXTERNAL:
1073                 return "external";
1074         case SEARCH_BUILTIN:
1075                 return "built-in";
1076         default:
1077                 return s->path;
1078         }
1079 }
1080
1081 static bool depmod_is_path_starts_with(const char *path,
1082                                        size_t pathlen,
1083                                        const char *prefix,
1084                                        size_t prefix_len)
1085 {
1086         if (pathlen <= prefix_len)
1087                 return false;
1088         if (path[prefix_len] != '/')
1089                 return false;
1090         if (memcmp(path, prefix, prefix_len) != 0)
1091                 return false;
1092
1093         return true;
1094 }
1095
1096 /* returns if existing module @mod is higher priority than newpath.
1097  * note this is the inverse of module-init-tools is_higher_priority()
1098  */
1099 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)
1100 {
1101         const struct cfg *cfg = depmod->cfg;
1102         const struct cfg_override *ov;
1103         const struct cfg_search *se;
1104         const struct cfg_external *ext;
1105
1106         /* baselen includes the last '/' and mod->baselen doesn't. So it's
1107          * actually correct to use modnamelen in the first and modnamesz in
1108          * the latter */
1109         size_t newlen = baselen + modnamelen;
1110         size_t oldlen = mod->baselen + mod->modnamesz;
1111         const char *oldpath = mod->path;
1112         int i, bprio = -1, oldprio = -1, newprio = -1;
1113         size_t relnewlen = 0;
1114         size_t reloldlen = 0;
1115         const char *relnewpath = NULL;
1116         const char *reloldpath = NULL;
1117
1118         DBG("comparing priorities of %s and %s\n",
1119             oldpath, newpath);
1120
1121         if (strncmp(newpath, cfg->dirname, cfg->dirnamelen) == 0) {
1122                 relnewpath = newpath + cfg->dirnamelen + 1;
1123                 relnewlen = newlen - (cfg->dirnamelen + 1);
1124         }
1125         if (strncmp(oldpath, cfg->dirname, cfg->dirnamelen) == 0) {
1126                 reloldpath = oldpath + cfg->dirnamelen + 1;
1127                 reloldlen = oldlen - (cfg->dirnamelen + 1);
1128         }
1129
1130         for (ov = cfg->overrides; ov != NULL; ov = ov->next) {
1131                 DBG("override %s\n", ov->path);
1132                 if (relnewlen == ov->len &&
1133                     memcmp(ov->path, relnewpath, relnewlen) == 0)
1134                         return 0;
1135                 if (reloldlen == ov->len &&
1136                     memcmp(ov->path, reloldpath, reloldlen) == 0)
1137                         return 1;
1138         }
1139
1140         for (i = 0, se = cfg->searches; se != NULL; se = se->next, i++) {
1141                 DBG("search %s\n", search_to_string(se));
1142                 if (se->type == SEARCH_BUILTIN)
1143                         bprio = i;
1144                 else if (se->type == SEARCH_EXTERNAL) {
1145                         for (ext = cfg->externals; ext != NULL; ext = ext->next, i++) {
1146                                 if (depmod_is_path_starts_with(newpath,
1147                                                                newlen,
1148                                                                ext->path,
1149                                                                ext->len))
1150                                         newprio = i;
1151                                 if (depmod_is_path_starts_with(oldpath,
1152                                                                oldlen,
1153                                                                ext->path,
1154                                                                ext->len))
1155                                         oldprio = i;
1156                         }
1157                 } else if (relnewlen > se->len && relnewpath[se->len] == '/' &&
1158                          memcmp(se->path, relnewpath, se->len) == 0)
1159                         newprio = i;
1160                 else if (reloldlen > se->len && reloldpath[se->len] == '/' &&
1161                          memcmp(se->path, reloldpath, se->len) == 0)
1162                         oldprio = i;
1163         }
1164
1165         if (newprio < 0)
1166                 newprio = bprio;
1167         if (oldprio < 0)
1168                 oldprio = bprio;
1169
1170         DBG("priorities: built-in: %d, old: %d, new: %d\n",
1171             bprio, oldprio, newprio);
1172
1173         return newprio <= oldprio;
1174 }
1175
1176 static int depmod_modules_search_file(struct depmod *depmod, size_t baselen, size_t namelen, const char *path)
1177 {
1178         struct kmod_module *kmod;
1179         struct mod *mod;
1180         const char *relpath;
1181         char modname[PATH_MAX];
1182         size_t modnamelen;
1183         int err;
1184
1185         if (!path_ends_with_kmod_ext(path + baselen, namelen))
1186                 return 0;
1187
1188         if (path_to_modname(path, modname, &modnamelen) == NULL) {
1189                 ERR("could not get modname from path %s\n", path);
1190                 return -EINVAL;
1191         }
1192
1193         relpath = path + depmod->cfg->dirnamelen + 1;
1194         DBG("try %s (%s)\n", relpath, modname);
1195
1196         mod = hash_find(depmod->modules_by_name, modname);
1197         if (mod == NULL)
1198                 goto add;
1199
1200         if (depmod_module_is_higher_priority(depmod, mod, baselen,
1201                                                 namelen, modnamelen, path)) {
1202                 DBG("Ignored lower priority: %s, higher: %s\n",
1203                     path, mod->path);
1204                 return 0;
1205         }
1206
1207         DBG("Replace lower priority %s with new module %s\n",
1208             mod->relpath, relpath);
1209         err = depmod_module_del(depmod, mod);
1210         if (err < 0) {
1211                 ERR("could not del module %s: %s\n", mod->path, strerror(-err));
1212                 return err;
1213         }
1214
1215 add:
1216         err = kmod_module_new_from_path(depmod->ctx, path, &kmod);
1217         if (err < 0) {
1218                 ERR("could not create module %s: %s\n", path, strerror(-err));
1219                 return err;
1220         }
1221
1222         err = depmod_module_add(depmod, kmod);
1223         if (err < 0) {
1224                 ERR("could not add module %s: %s\n",
1225                     path, strerror(-err));
1226                 kmod_module_unref(kmod);
1227                 return err;
1228         }
1229         return 0;
1230 }
1231
1232 static int depmod_modules_search_dir(struct depmod *depmod, DIR *d, size_t baselen, struct scratchbuf *s_path)
1233 {
1234         struct dirent *de;
1235         int err = 0, dfd = dirfd(d);
1236         char *path;
1237
1238         while ((de = readdir(d)) != NULL) {
1239                 const char *name = de->d_name;
1240                 size_t namelen;
1241                 uint8_t is_dir;
1242
1243                 if (name[0] == '.' && (name[1] == '\0' ||
1244                                        (name[1] == '.' && name[2] == '\0')))
1245                         continue;
1246                 if (streq(name, "build") || streq(name, "source"))
1247                         continue;
1248                 namelen = strlen(name);
1249                 if (scratchbuf_alloc(s_path, baselen + namelen + 2) < 0) {
1250                         err = -ENOMEM;
1251                         ERR("No memory\n");
1252                         continue;
1253                 }
1254
1255                 path = scratchbuf_str(s_path);
1256                 memcpy(path + baselen, name, namelen + 1);
1257
1258                 if (de->d_type == DT_REG)
1259                         is_dir = 0;
1260                 else if (de->d_type == DT_DIR)
1261                         is_dir = 1;
1262                 else {
1263                         struct stat st;
1264                         if (fstatat(dfd, name, &st, 0) < 0) {
1265                                 ERR("fstatat(%d, %s): %m\n", dfd, name);
1266                                 continue;
1267                         } else if (S_ISREG(st.st_mode))
1268                                 is_dir = 0;
1269                         else if (S_ISDIR(st.st_mode))
1270                                 is_dir = 1;
1271                         else {
1272                                 ERR("unsupported file type %s: %o\n",
1273                                     path, st.st_mode & S_IFMT);
1274                                 continue;
1275                         }
1276                 }
1277
1278                 if (is_dir) {
1279                         int fd;
1280                         DIR *subdir;
1281                         fd = openat(dfd, name, O_RDONLY);
1282                         if (fd < 0) {
1283                                 ERR("openat(%d, %s, O_RDONLY): %m\n",
1284                                     dfd, name);
1285                                 continue;
1286                         }
1287                         subdir = fdopendir(fd);
1288                         if (subdir == NULL) {
1289                                 ERR("fdopendir(%d): %m\n", fd);
1290                                 close(fd);
1291                                 continue;
1292                         }
1293                         path[baselen + namelen] = '/';
1294                         path[baselen + namelen + 1] = '\0';
1295                         err = depmod_modules_search_dir(depmod, subdir,
1296                                                         baselen + namelen + 1,
1297                                                         s_path);
1298                         closedir(subdir);
1299                 } else {
1300                         err = depmod_modules_search_file(depmod, baselen,
1301                                                          namelen, path);
1302                 }
1303
1304                 if (err < 0) {
1305                         path[baselen + namelen] = '\0';
1306                         ERR("failed %s: %s\n", path, strerror(-err));
1307                         err = 0; /* ignore errors */
1308                 }
1309         }
1310         return err;
1311 }
1312
1313 static int depmod_modules_search_path(struct depmod *depmod,
1314                                       const char *path)
1315 {
1316         char buf[256];
1317         _cleanup_(scratchbuf_release) struct scratchbuf s_path_buf =
1318                 SCRATCHBUF_INITIALIZER(buf);
1319         char *path_buf;
1320         DIR *d;
1321         size_t baselen;
1322         int err;
1323
1324         d = opendir(path);
1325         if (d == NULL) {
1326                 err = -errno;
1327                 ERR("could not open directory %s: %m\n", path);
1328                 return err;
1329         }
1330
1331         baselen = strlen(path);
1332
1333         if (scratchbuf_alloc(&s_path_buf, baselen + 2) < 0) {
1334                 err = -ENOMEM;
1335                 goto out;
1336         }
1337         path_buf = scratchbuf_str(&s_path_buf);
1338
1339         memcpy(path_buf, path, baselen);
1340         path_buf[baselen] = '/';
1341         baselen++;
1342         path_buf[baselen] = '\0';
1343
1344         err = depmod_modules_search_dir(depmod, d, baselen, &s_path_buf);
1345 out:
1346         closedir(d);
1347         return err;
1348 }
1349
1350 static int depmod_modules_search(struct depmod *depmod)
1351 {
1352         int err;
1353         struct cfg_external *ext;
1354
1355         err = depmod_modules_search_path(depmod, depmod->cfg->dirname);
1356         if (err < 0)
1357                 return err;
1358
1359         for (ext = depmod->cfg->externals; ext != NULL; ext = ext->next) {
1360                 err = depmod_modules_search_path(depmod, ext->path);
1361                 if (err < 0 && err == -ENOENT)
1362                         /* ignore external dir absense */
1363                         continue;
1364         }
1365
1366         return 0;
1367 }
1368
1369 static int mod_cmp(const void *pa, const void *pb) {
1370         const struct mod *a = *(const struct mod **)pa;
1371         const struct mod *b = *(const struct mod **)pb;
1372         return a->sort_idx - b->sort_idx;
1373 }
1374
1375 static int depmod_modules_build_array(struct depmod *depmod)
1376 {
1377         struct hash_iter module_iter;
1378         const void *v;
1379         int err;
1380
1381         hash_iter_init(depmod->modules_by_name, &module_iter);
1382         while (hash_iter_next(&module_iter, NULL, &v)) {
1383                 struct mod *mod = (struct mod *) v;
1384                 mod->idx = depmod->modules.count;
1385                 err = array_append(&depmod->modules, mod);
1386                 if (err < 0)
1387                         return err;
1388         }
1389
1390         return 0;
1391 }
1392
1393 static FILE *dfdopen(const char *dname, const char *filename, int flags,
1394                      const char *mode)
1395 {
1396         int fd, dfd;
1397         FILE *ret;
1398
1399         dfd = open(dname, O_RDONLY);
1400         if (dfd < 0) {
1401                 WRN("could not open directory %s: %m\n", dname);
1402                 return NULL;
1403         }
1404
1405         fd = openat(dfd, filename, flags);
1406         if (fd < 0) {
1407                 WRN("could not open %s at %s: %m\n", filename, dname);
1408                 ret = NULL;
1409         } else {
1410                 ret = fdopen(fd, mode);
1411                 if (!ret) {
1412                         WRN("could not associate stream with %s: %m\n", filename);
1413                         close(fd);
1414                 }
1415         }
1416         close(dfd);
1417         return ret;
1418 }
1419
1420
1421
1422 static void depmod_modules_sort(struct depmod *depmod)
1423 {
1424         char line[PATH_MAX];
1425         const char *order_file = "modules.order";
1426         FILE *fp;
1427         unsigned idx = 0, total = 0;
1428
1429         fp = dfdopen(depmod->cfg->dirname, order_file, O_RDONLY, "r");
1430         if (fp == NULL)
1431                 return;
1432
1433         while (fgets(line, sizeof(line), fp) != NULL) {
1434                 size_t len = strlen(line);
1435                 idx++;
1436                 if (len == 0)
1437                         continue;
1438                 if (line[len - 1] != '\n') {
1439                         ERR("%s/%s:%u corrupted line misses '\\n'\n",
1440                                 depmod->cfg->dirname, order_file, idx);
1441                         goto corrupted;
1442                 }
1443         }
1444         total = idx + 1;
1445         idx = 0;
1446         fseek(fp, 0, SEEK_SET);
1447         while (fgets(line, sizeof(line), fp) != NULL) {
1448                 size_t len = strlen(line);
1449                 struct mod *mod;
1450
1451                 idx++;
1452                 if (len == 0)
1453                         continue;
1454                 line[len - 1] = '\0';
1455
1456                 mod = hash_find(depmod->modules_by_uncrelpath, line);
1457                 if (mod == NULL)
1458                         continue;
1459                 mod->sort_idx = idx - total;
1460         }
1461
1462         array_sort(&depmod->modules, mod_cmp);
1463         for (idx = 0; idx < depmod->modules.count; idx++) {
1464                 struct mod *m = depmod->modules.array[idx];
1465                 m->idx = idx;
1466         }
1467
1468 corrupted:
1469         fclose(fp);
1470 }
1471
1472 static int depmod_symbol_add(struct depmod *depmod, const char *name,
1473                                         bool prefix_skipped, uint64_t crc,
1474                                         const struct mod *owner)
1475 {
1476         size_t namelen;
1477         int err;
1478         struct symbol *sym;
1479
1480         if (!prefix_skipped && (name[0] == depmod->cfg->sym_prefix))
1481                 name++;
1482
1483         namelen = strlen(name) + 1;
1484         sym = malloc(sizeof(struct symbol) + namelen);
1485         if (sym == NULL)
1486                 return -ENOMEM;
1487
1488         sym->owner = (struct mod *)owner;
1489         sym->crc = crc;
1490         memcpy(sym->name, name, namelen);
1491
1492         err = hash_add(depmod->symbols, sym->name, sym);
1493         if (err < 0) {
1494                 free(sym);
1495                 return err;
1496         }
1497
1498         DBG("add %p sym=%s, owner=%p %s\n", sym, sym->name, owner,
1499             owner != NULL ? owner->path : "");
1500
1501         return 0;
1502 }
1503
1504 static struct symbol *depmod_symbol_find(const struct depmod *depmod,
1505                                                         const char *name)
1506 {
1507         if (name[0] == '.') /* PPC64 needs this: .foo == foo */
1508                 name++;
1509         if (name[0] == depmod->cfg->sym_prefix)
1510                 name++;
1511         return hash_find(depmod->symbols, name);
1512 }
1513
1514 static int depmod_load_modules(struct depmod *depmod)
1515 {
1516         struct mod **itr, **itr_end;
1517
1518         DBG("load symbols (%zd modules)\n", depmod->modules.count);
1519
1520         itr = (struct mod **)depmod->modules.array;
1521         itr_end = itr + depmod->modules.count;
1522         for (; itr < itr_end; itr++) {
1523                 struct mod *mod = *itr;
1524                 struct kmod_list *l, *list = NULL;
1525                 int err = kmod_module_get_symbols(mod->kmod, &list);
1526                 if (err < 0) {
1527                         if (err == -ENOENT)
1528                                 DBG("ignoring %s: no symbols\n", mod->path);
1529                         else
1530                                 ERR("failed to load symbols from %s: %s\n",
1531                                                 mod->path, strerror(-err));
1532                         goto load_info;
1533                 }
1534                 kmod_list_foreach(l, list) {
1535                         const char *name = kmod_module_symbol_get_symbol(l);
1536                         uint64_t crc = kmod_module_symbol_get_crc(l);
1537                         depmod_symbol_add(depmod, name, false, crc, mod);
1538                 }
1539                 kmod_module_symbols_free_list(list);
1540
1541 load_info:
1542                 kmod_module_get_info(mod->kmod, &mod->info_list);
1543                 kmod_module_get_dependency_symbols(mod->kmod,
1544                                                    &mod->dep_sym_list);
1545                 kmod_module_unref(mod->kmod);
1546                 mod->kmod = NULL;
1547         }
1548
1549         DBG("loaded symbols (%zd modules, %u symbols)\n",
1550             depmod->modules.count, hash_get_count(depmod->symbols));
1551
1552         return 0;
1553 }
1554
1555 static int depmod_load_module_dependencies(struct depmod *depmod, struct mod *mod)
1556 {
1557         const struct cfg *cfg = depmod->cfg;
1558         struct kmod_list *l;
1559
1560         DBG("do dependencies of %s\n", mod->path);
1561         kmod_list_foreach(l, mod->dep_sym_list) {
1562                 const char *name = kmod_module_dependency_symbol_get_symbol(l);
1563                 uint64_t crc = kmod_module_dependency_symbol_get_crc(l);
1564                 int bindtype = kmod_module_dependency_symbol_get_bind(l);
1565                 struct symbol *sym = depmod_symbol_find(depmod, name);
1566                 uint8_t is_weak = bindtype == KMOD_SYMBOL_WEAK;
1567
1568                 if (sym == NULL) {
1569                         DBG("%s needs (%c) unknown symbol %s\n",
1570                             mod->path, bindtype, name);
1571                         if (cfg->print_unknown && !is_weak)
1572                                 WRN("%s needs unknown symbol %s\n",
1573                                     mod->path, name);
1574                         continue;
1575                 }
1576
1577                 if (cfg->check_symvers && sym->crc != crc && !is_weak) {
1578                         DBG("symbol %s (%#"PRIx64") module %s (%#"PRIx64")\n",
1579                             sym->name, sym->crc, mod->path, crc);
1580                         if (cfg->print_unknown)
1581                                 WRN("%s disagrees about version of symbol %s\n",
1582                                     mod->path, name);
1583                 }
1584
1585                 mod_add_dependency(mod, sym);
1586         }
1587
1588         return 0;
1589 }
1590
1591 static int depmod_load_dependencies(struct depmod *depmod)
1592 {
1593         struct mod **itr, **itr_end;
1594
1595         DBG("load dependencies (%zd modules, %u symbols)\n",
1596             depmod->modules.count, hash_get_count(depmod->symbols));
1597
1598         itr = (struct mod **)depmod->modules.array;
1599         itr_end = itr + depmod->modules.count;
1600         for (; itr < itr_end; itr++) {
1601                 struct mod *mod = *itr;
1602
1603                 if (mod->dep_sym_list == NULL) {
1604                         DBG("ignoring %s: no dependency symbols\n", mod->path);
1605                         continue;
1606                 }
1607
1608                 depmod_load_module_dependencies(depmod, mod);
1609         }
1610
1611         DBG("loaded dependencies (%zd modules, %u symbols)\n",
1612             depmod->modules.count, hash_get_count(depmod->symbols));
1613
1614         return 0;
1615 }
1616
1617 static int dep_cmp(const void *pa, const void *pb)
1618 {
1619         const struct mod *a = *(const struct mod **)pa;
1620         const struct mod *b = *(const struct mod **)pb;
1621         return a->dep_sort_idx - b->dep_sort_idx;
1622 }
1623
1624 static void depmod_sort_dependencies(struct depmod *depmod)
1625 {
1626         struct mod **itr, **itr_end;
1627         itr = (struct mod **)depmod->modules.array;
1628         itr_end = itr + depmod->modules.count;
1629         for (; itr < itr_end; itr++) {
1630                 struct mod *m = *itr;
1631                 if (m->deps.count > 1)
1632                         array_sort(&m->deps, dep_cmp);
1633         }
1634 }
1635
1636 struct vertex {
1637         struct vertex *parent;
1638         struct mod *mod;
1639 };
1640
1641 static struct vertex *vertex_new(struct mod *mod, struct vertex *parent)
1642 {
1643         struct vertex *v;
1644
1645         v = malloc(sizeof(*v));
1646         if (v == NULL)
1647                 return NULL;
1648
1649         v->parent = parent;
1650         v->mod = mod;
1651         return v;
1652 }
1653
1654 static void depmod_list_remove_data(struct kmod_list **list, void *data)
1655 {
1656         struct kmod_list *l;
1657
1658         l = kmod_list_remove_data(*list, data);
1659         *list = l;
1660 }
1661
1662 static int depmod_report_one_cycle(struct depmod *depmod,
1663                                    struct vertex *vertex,
1664                                    struct kmod_list **roots,
1665                                    struct hash *loop_set)
1666 {
1667         const char sep[] = " -> ";
1668         size_t sz;
1669         char *buf;
1670         struct array reverse;
1671         int i;
1672         int n;
1673         struct vertex *v;
1674         int rc;
1675
1676         array_init(&reverse, 3);
1677
1678         sz = 0;
1679         for (v = vertex->parent, n = 0;
1680              v != NULL;
1681              v = v->parent, n++) {
1682
1683                 sz += v->mod->modnamesz - 1;
1684                 array_append(&reverse, v);
1685                 rc = hash_add(loop_set, v->mod->modname, NULL);
1686                 if (rc != 0)
1687                         return rc;
1688                 /* the hash will be freed where created */
1689         }
1690         sz += vertex->mod->modnamesz - 1;
1691
1692         buf = malloc(sz + n * strlen(sep) + 1);
1693
1694         sz = 0;
1695         for (i = reverse.count - 1; i >= 0; i--) {
1696                 size_t len;
1697
1698                 v = reverse.array[i];
1699
1700                 len = v->mod->modnamesz - 1;
1701                 memcpy(buf + sz, v->mod->modname, len);
1702                 sz += len;
1703                 strcpy(buf + sz, sep);
1704                 sz += strlen(sep);
1705
1706                 depmod_list_remove_data(roots, v->mod);
1707         }
1708         strcpy(buf + sz, vertex->mod->modname);
1709         ERR("Cycle detected: %s\n", buf);
1710
1711         free(buf);
1712         array_free_array(&reverse);
1713
1714         return 0;
1715 }
1716
1717 static int depmod_report_cycles_from_root(struct depmod *depmod,
1718                                           struct mod *root_mod,
1719                                           struct kmod_list **roots,
1720                                           void **stack,
1721                                           size_t stack_size,
1722                                           struct hash *loop_set)
1723 {
1724         struct kmod_list *free_list = NULL; /* struct vertex */
1725         struct kmod_list *l;
1726         struct vertex *root;
1727         struct vertex *vertex;
1728         struct vertex *v;
1729         struct mod *m;
1730         struct mod **itr, **itr_end;
1731         size_t is;
1732         int ret = -ENOMEM;
1733
1734         root = vertex_new(root_mod, NULL);
1735         if (root == NULL) {
1736                 ERR("No memory to report cycles\n");
1737                 goto out;
1738         }
1739
1740         l = kmod_list_append(free_list, root);
1741         if (l == NULL) {
1742                 ERR("No memory to report cycles\n");
1743                 goto out;
1744         }
1745         free_list = l;
1746
1747         is = 0;
1748         stack[is++] = (void *)root;
1749
1750         while (is > 0) {
1751                 vertex = stack[--is];
1752                 m = vertex->mod;
1753                 /*
1754                  * because of the topological sort we can start only
1755                  * from part of a loop or from a branch after a loop
1756                  */
1757                 if (m->visited && m == root->mod) {
1758                         int rc;
1759                         rc = depmod_report_one_cycle(depmod, vertex,
1760                                                      roots, loop_set);
1761                         if (rc != 0) {
1762                                 ret = rc;
1763                                 goto out;
1764                         }
1765                         continue;
1766                 }
1767
1768                 m->visited = true;
1769                 if (m->deps.count == 0) {
1770                         /*
1771                          * boundary condition: if there is more than one
1772                          * single node branch (not a loop), it is
1773                          * recognized as a loop by the code above:
1774                          * m->visited because more then one,
1775                          * m == root->mod since it is a single node.
1776                          * So, prevent deeping into the branch second
1777                          * time.
1778                          */
1779                         depmod_list_remove_data(roots, m);
1780
1781                         continue;
1782                 }
1783
1784                 itr = (struct mod **) m->deps.array;
1785                 itr_end = itr + m->deps.count;
1786                 for (; itr < itr_end; itr++) {
1787                         struct mod *dep = *itr;
1788                         v = vertex_new(dep, vertex);
1789                         if (v == NULL) {
1790                                 ERR("No memory to report cycles\n");
1791                                 goto out;
1792                         }
1793                         assert(is < stack_size);
1794                         stack[is++] = v;
1795
1796                         l = kmod_list_append(free_list, v);
1797                         if (l == NULL) {
1798                                 ERR("No memory to report cycles\n");
1799                                 goto out;
1800                         }
1801                         free_list = l;
1802
1803                 }
1804         }
1805         ret = 0;
1806
1807 out:
1808         while (free_list) {
1809                 v = free_list->data;
1810                 l = kmod_list_remove(free_list);
1811                 free_list = l;
1812                 free(v);
1813         }
1814
1815         return ret;
1816 }
1817
1818 static void depmod_report_cycles(struct depmod *depmod, uint16_t n_mods,
1819                                  uint16_t *users)
1820 {
1821         int num_cyclic = 0;
1822         struct kmod_list *roots = NULL; /* struct mod */
1823         struct kmod_list *l;
1824         size_t n_r; /* local n_roots */
1825         int i;
1826         int err;
1827         _cleanup_free_ void **stack = NULL;
1828         struct mod *m;
1829         struct mod *root;
1830         struct hash *loop_set;
1831
1832         for (i = 0, n_r = 0; i < n_mods; i++) {
1833                 if (users[i] <= 0)
1834                         continue;
1835                 m = depmod->modules.array[i];
1836                 l = kmod_list_append(roots, m);
1837                 if (l == NULL) {
1838                         ERR("No memory to report cycles\n");
1839                         goto out_list;
1840                 }
1841                 roots = l;
1842                 n_r++;
1843         }
1844
1845         stack = malloc(n_r * sizeof(void *));
1846         if (stack == NULL) {
1847                 ERR("No memory to report cycles\n");
1848                 goto out_list;
1849         }
1850
1851         loop_set = hash_new(16, NULL);
1852         if (loop_set == NULL) {
1853                 ERR("No memory to report cycles\n");
1854                 goto out_list;
1855         }
1856
1857         while (roots != NULL) {
1858                 root = roots->data;
1859                 l = kmod_list_remove(roots);
1860                 roots = l;
1861                 err = depmod_report_cycles_from_root(depmod,
1862                                                      root,
1863                                                      &roots,
1864                                                      stack, n_r, loop_set);
1865                 if (err < 0)
1866                         goto out_hash;
1867         }
1868
1869         num_cyclic = hash_get_count(loop_set);
1870         ERR("Found %d modules in dependency cycles!\n", num_cyclic);
1871
1872 out_hash:
1873         hash_free(loop_set);
1874 out_list:
1875         while (roots != NULL) {
1876                 /* no need to free data, come from outside */
1877                 roots = kmod_list_remove(roots);
1878         }
1879 }
1880
1881 static int depmod_calculate_dependencies(struct depmod *depmod)
1882 {
1883         const struct mod **itrm;
1884         uint16_t *users, *roots, *sorted;
1885         uint16_t i, n_roots = 0, n_sorted = 0, n_mods = depmod->modules.count;
1886         int ret = 0;
1887
1888         users = malloc(sizeof(uint16_t) * n_mods * 3);
1889         if (users == NULL)
1890                 return -ENOMEM;
1891         roots = users + n_mods;
1892         sorted = roots + n_mods;
1893
1894         DBG("calculate dependencies and ordering (%hu modules)\n", n_mods);
1895
1896         assert(depmod->modules.count < UINT16_MAX);
1897
1898         /* populate modules users (how many modules uses it) */
1899         itrm = (const struct mod **)depmod->modules.array;
1900         for (i = 0; i < n_mods; i++, itrm++) {
1901                 const struct mod *m = *itrm;
1902                 users[i] = m->users;
1903                 if (users[i] == 0) {
1904                         roots[n_roots] = i;
1905                         n_roots++;
1906                 }
1907         }
1908
1909         /* topological sort (outputs modules without users first) */
1910         while (n_roots > 0) {
1911                 const struct mod **itr_dst, **itr_dst_end;
1912                 struct mod *src;
1913                 uint16_t src_idx = roots[--n_roots];
1914
1915                 src = depmod->modules.array[src_idx];
1916                 src->dep_sort_idx = n_sorted;
1917                 sorted[n_sorted] = src_idx;
1918                 n_sorted++;
1919
1920                 itr_dst = (const struct mod **)src->deps.array;
1921                 itr_dst_end = itr_dst + src->deps.count;
1922                 for (; itr_dst < itr_dst_end; itr_dst++) {
1923                         const struct mod *dst = *itr_dst;
1924                         uint16_t dst_idx = dst->idx;
1925                         assert(users[dst_idx] > 0);
1926                         users[dst_idx]--;
1927                         if (users[dst_idx] == 0) {
1928                                 roots[n_roots] = dst_idx;
1929                                 n_roots++;
1930                         }
1931                 }
1932         }
1933
1934         if (n_sorted < n_mods) {
1935                 depmod_report_cycles(depmod, n_mods, users);
1936                 ret = -EINVAL;
1937                 goto exit;
1938         }
1939
1940         depmod_sort_dependencies(depmod);
1941
1942         DBG("calculated dependencies and ordering (%hu modules)\n", n_mods);
1943
1944 exit:
1945         free(users);
1946         return ret;
1947 }
1948
1949 static int depmod_load(struct depmod *depmod)
1950 {
1951         int err;
1952
1953         err = depmod_load_modules(depmod);
1954         if (err < 0)
1955                 return err;
1956
1957         err = depmod_load_dependencies(depmod);
1958         if (err < 0)
1959                 return err;
1960
1961         err = depmod_calculate_dependencies(depmod);
1962         if (err < 0)
1963                 return err;
1964
1965         return 0;
1966 }
1967
1968 static size_t mod_count_all_dependencies(const struct mod *mod)
1969 {
1970         size_t i, count = 0;
1971         for (i = 0; i < mod->deps.count; i++) {
1972                 const struct mod *d = mod->deps.array[i];
1973                 count += 1 + mod_count_all_dependencies(d);
1974         }
1975         return count;
1976 }
1977
1978 static int mod_fill_all_unique_dependencies(const struct mod *mod, const struct mod **deps, size_t n_deps, size_t *last)
1979 {
1980         size_t i;
1981         int err = 0;
1982         for (i = 0; i < mod->deps.count; i++) {
1983                 const struct mod *d = mod->deps.array[i];
1984                 size_t j;
1985                 uint8_t exists = 0;
1986
1987                 for (j = 0; j < *last; j++) {
1988                         if (deps[j] == d) {
1989                                 exists = 1;
1990                                 break;
1991                         }
1992                 }
1993
1994                 if (exists)
1995                         continue;
1996
1997                 if (*last >= n_deps)
1998                         return -ENOSPC;
1999                 deps[*last] = d;
2000                 (*last)++;
2001                 err = mod_fill_all_unique_dependencies(d, deps, n_deps, last);
2002                 if (err < 0)
2003                         break;
2004         }
2005         return err;
2006 }
2007
2008 static const struct mod **mod_get_all_sorted_dependencies(const struct mod *mod, size_t *n_deps)
2009 {
2010         const struct mod **deps;
2011         size_t last = 0;
2012
2013         *n_deps = mod_count_all_dependencies(mod);
2014         if (*n_deps == 0)
2015                 return NULL;
2016
2017         deps = malloc(sizeof(struct mod *) * (*n_deps));
2018         if (deps == NULL)
2019                 return NULL;
2020
2021         if (mod_fill_all_unique_dependencies(mod, deps, *n_deps, &last) < 0) {
2022                 free(deps);
2023                 return NULL;
2024         }
2025
2026         qsort(deps, last, sizeof(struct mod *), dep_cmp);
2027         *n_deps = last;
2028         return deps;
2029 }
2030
2031 static inline const char *mod_get_compressed_path(const struct mod *mod)
2032 {
2033         if (mod->relpath != NULL)
2034                 return mod->relpath;
2035         return mod->path;
2036 }
2037
2038 static int output_deps(struct depmod *depmod, FILE *out)
2039 {
2040         size_t i;
2041
2042         for (i = 0; i < depmod->modules.count; i++) {
2043                 const struct mod **deps, *mod = depmod->modules.array[i];
2044                 const char *p = mod_get_compressed_path(mod);
2045                 size_t j, n_deps;
2046
2047                 fprintf(out, "%s:", p);
2048
2049                 if (mod->deps.count == 0)
2050                         goto end;
2051
2052                 deps = mod_get_all_sorted_dependencies(mod, &n_deps);
2053                 if (deps == NULL) {
2054                         ERR("could not get all sorted dependencies of %s\n", p);
2055                         goto end;
2056                 }
2057
2058                 for (j = 0; j < n_deps; j++) {
2059                         const struct mod *d = deps[j];
2060                         fprintf(out, " %s", mod_get_compressed_path(d));
2061                 }
2062                 free(deps);
2063         end:
2064                 putc('\n', out);
2065         }
2066
2067         return 0;
2068 }
2069
2070 static int output_deps_bin(struct depmod *depmod, FILE *out)
2071 {
2072         struct index_node *idx;
2073         size_t i;
2074
2075         if (out == stdout)
2076                 return 0;
2077
2078         idx = index_create();
2079         if (idx == NULL)
2080                 return -ENOMEM;
2081
2082         for (i = 0; i < depmod->modules.count; i++) {
2083                 const struct mod **deps, *mod = depmod->modules.array[i];
2084                 const char *p = mod_get_compressed_path(mod);
2085                 char *line;
2086                 size_t j, n_deps, linepos, linelen, slen;
2087                 int duplicate;
2088
2089                 deps = mod_get_all_sorted_dependencies(mod, &n_deps);
2090                 if (deps == NULL && n_deps > 0) {
2091                         ERR("could not get all sorted dependencies of %s\n", p);
2092                         continue;
2093                 }
2094
2095                 linelen = strlen(p) + 1;
2096                 for (j = 0; j < n_deps; j++) {
2097                         const struct mod *d = deps[j];
2098                         linelen += 1 + strlen(mod_get_compressed_path(d));
2099                 }
2100
2101                 line = malloc(linelen + 1);
2102                 if (line == NULL) {
2103                         free(deps);
2104                         ERR("modules.deps.bin: out of memory\n");
2105                         continue;
2106                 }
2107
2108                 linepos = 0;
2109                 slen = strlen(p);
2110                 memcpy(line + linepos, p, slen);
2111                 linepos += slen;
2112                 line[linepos] = ':';
2113                 linepos++;
2114
2115                 for (j = 0; j < n_deps; j++) {
2116                         const struct mod *d = deps[j];
2117                         const char *dp;
2118
2119                         line[linepos] = ' ';
2120                         linepos++;
2121
2122                         dp = mod_get_compressed_path(d);
2123                         slen = strlen(dp);
2124                         memcpy(line + linepos, dp, slen);
2125                         linepos += slen;
2126                 }
2127                 line[linepos] = '\0';
2128
2129                 duplicate = index_insert(idx, mod->modname, line, mod->idx);
2130                 if (duplicate && depmod->cfg->warn_dups)
2131                         WRN("duplicate module deps:\n%s\n", line);
2132                 free(line);
2133                 free(deps);
2134         }
2135
2136         index_write(idx, out);
2137         index_destroy(idx);
2138
2139         return 0;
2140 }
2141
2142 static int output_aliases(struct depmod *depmod, FILE *out)
2143 {
2144         size_t i;
2145
2146         fputs("# Aliases extracted from modules themselves.\n", out);
2147
2148         for (i = 0; i < depmod->modules.count; i++) {
2149                 const struct mod *mod = depmod->modules.array[i];
2150                 struct kmod_list *l;
2151
2152                 kmod_list_foreach(l, mod->info_list) {
2153                         const char *key = kmod_module_info_get_key(l);
2154                         const char *value = kmod_module_info_get_value(l);
2155
2156                         if (!streq(key, "alias"))
2157                                 continue;
2158
2159                         fprintf(out, "alias %s %s\n", value, mod->modname);
2160                 }
2161         }
2162
2163         return 0;
2164 }
2165
2166 static int output_aliases_bin(struct depmod *depmod, FILE *out)
2167 {
2168         struct index_node *idx;
2169         size_t i;
2170
2171         if (out == stdout)
2172                 return 0;
2173
2174         idx = index_create();
2175         if (idx == NULL)
2176                 return -ENOMEM;
2177
2178         for (i = 0; i < depmod->modules.count; i++) {
2179                 const struct mod *mod = depmod->modules.array[i];
2180                 struct kmod_list *l;
2181
2182                 kmod_list_foreach(l, mod->info_list) {
2183                         const char *key = kmod_module_info_get_key(l);
2184                         const char *value = kmod_module_info_get_value(l);
2185                         char buf[PATH_MAX];
2186                         const char *alias;
2187                         int duplicate;
2188
2189                         if (!streq(key, "alias"))
2190                                 continue;
2191
2192                         if (alias_normalize(value, buf, NULL) < 0) {
2193                                 WRN("Unmatched bracket in %s\n", value);
2194                                 continue;
2195                         }
2196                         alias = buf;
2197
2198                         duplicate = index_insert(idx, alias, mod->modname,
2199                                                  mod->idx);
2200                         if (duplicate && depmod->cfg->warn_dups)
2201                                 WRN("duplicate module alias:\n%s %s\n",
2202                                     alias, mod->modname);
2203                 }
2204         }
2205
2206         index_write(idx, out);
2207         index_destroy(idx);
2208
2209         return 0;
2210 }
2211
2212 static int output_softdeps(struct depmod *depmod, FILE *out)
2213 {
2214         size_t i;
2215
2216         fputs("# Soft dependencies extracted from modules themselves.\n", out);
2217
2218         for (i = 0; i < depmod->modules.count; i++) {
2219                 const struct mod *mod = depmod->modules.array[i];
2220                 struct kmod_list *l;
2221
2222                 kmod_list_foreach(l, mod->info_list) {
2223                         const char *key = kmod_module_info_get_key(l);
2224                         const char *value = kmod_module_info_get_value(l);
2225
2226                         if (!streq(key, "softdep"))
2227                                 continue;
2228
2229                         fprintf(out, "softdep %s %s\n", mod->modname, value);
2230                 }
2231         }
2232
2233         return 0;
2234 }
2235
2236 static int output_symbols(struct depmod *depmod, FILE *out)
2237 {
2238         struct hash_iter iter;
2239         const void *v;
2240
2241         fputs("# Aliases for symbols, used by symbol_request().\n", out);
2242
2243         hash_iter_init(depmod->symbols, &iter);
2244
2245         while (hash_iter_next(&iter, NULL, &v)) {
2246                 const struct symbol *sym = v;
2247                 if (sym->owner == NULL)
2248                         continue;
2249
2250                 fprintf(out, "alias symbol:%s %s\n",
2251                                         sym->name, sym->owner->modname);
2252         }
2253
2254         return 0;
2255 }
2256
2257 static int output_symbols_bin(struct depmod *depmod, FILE *out)
2258 {
2259         struct index_node *idx;
2260         char alias[1024];
2261         _cleanup_(scratchbuf_release) struct scratchbuf salias =
2262                 SCRATCHBUF_INITIALIZER(alias);
2263         size_t baselen = sizeof("symbol:") - 1;
2264         struct hash_iter iter;
2265         const void *v;
2266         int ret = 0;
2267
2268         if (out == stdout)
2269                 return 0;
2270
2271         idx = index_create();
2272         if (idx == NULL)
2273                 return -ENOMEM;
2274
2275         memcpy(alias, "symbol:", baselen);
2276
2277         hash_iter_init(depmod->symbols, &iter);
2278
2279         while (hash_iter_next(&iter, NULL, &v)) {
2280                 int duplicate;
2281                 const struct symbol *sym = v;
2282                 size_t len;
2283
2284                 if (sym->owner == NULL)
2285                         continue;
2286
2287                 len = strlen(sym->name);
2288
2289                 if (scratchbuf_alloc(&salias, baselen + len + 1) < 0) {
2290                         ret = -ENOMEM;
2291                         goto err_scratchbuf;
2292                 }
2293                 memcpy(scratchbuf_str(&salias) + baselen, sym->name, len + 1);
2294                 duplicate = index_insert(idx, alias, sym->owner->modname,
2295                                                         sym->owner->idx);
2296
2297                 if (duplicate && depmod->cfg->warn_dups)
2298                         WRN("duplicate module syms:\n%s %s\n",
2299                                                 alias, sym->owner->modname);
2300         }
2301
2302         index_write(idx, out);
2303
2304 err_scratchbuf:
2305         index_destroy(idx);
2306
2307         if (ret < 0)
2308                 ERR("output symbols: %s\n", strerror(-ret));
2309
2310         return ret;
2311 }
2312
2313 static int output_builtin_bin(struct depmod *depmod, FILE *out)
2314 {
2315         FILE *in;
2316         struct index_node *idx;
2317         char line[PATH_MAX], modname[PATH_MAX];
2318
2319         if (out == stdout)
2320                 return 0;
2321
2322         in = dfdopen(depmod->cfg->dirname, "modules.builtin", O_RDONLY, "r");
2323         if (in == NULL)
2324                 return 0;
2325
2326         idx = index_create();
2327         if (idx == NULL) {
2328                 fclose(in);
2329                 return -ENOMEM;
2330         }
2331
2332         while (fgets(line, sizeof(line), in) != NULL) {
2333                 if (!isalpha(line[0])) {
2334                         ERR("Invalid modules.builtin line: %s\n", line);
2335                         continue;
2336                 }
2337
2338                 path_to_modname(line, modname, NULL);
2339                 index_insert(idx, modname, "", 0);
2340         }
2341
2342         index_write(idx, out);
2343         index_destroy(idx);
2344         fclose(in);
2345
2346         return 0;
2347 }
2348
2349 static int output_devname(struct depmod *depmod, FILE *out)
2350 {
2351         size_t i;
2352         bool empty = true;
2353
2354         for (i = 0; i < depmod->modules.count; i++) {
2355                 const struct mod *mod = depmod->modules.array[i];
2356                 struct kmod_list *l;
2357                 const char *devname = NULL;
2358                 char type = '\0';
2359                 unsigned int major = 0, minor = 0;
2360
2361                 kmod_list_foreach(l, mod->info_list) {
2362                         const char *key = kmod_module_info_get_key(l);
2363                         const char *value = kmod_module_info_get_value(l);
2364                         unsigned int maj, min;
2365
2366                         if (!streq(key, "alias"))
2367                                 continue;
2368
2369                         if (strstartswith(value, "devname:"))
2370                                 devname = value + sizeof("devname:") - 1;
2371                         else if (sscanf(value, "char-major-%u-%u",
2372                                                 &maj, &min) == 2) {
2373                                 type = 'c';
2374                                 major = maj;
2375                                 minor = min;
2376                         } else if (sscanf(value, "block-major-%u-%u",
2377                                                 &maj, &min) == 2) {
2378                                 type = 'b';
2379                                 major = maj;
2380                                 minor = min;
2381                         }
2382
2383                         if (type != '\0' && devname != NULL)
2384                                 break;
2385                 }
2386
2387                 if (devname != NULL) {
2388                         if (type != '\0') {
2389                                 if (empty) {
2390                                         fputs("# Device nodes to trigger on-demand module loading.\n",
2391                                               out);
2392                                         empty = false;
2393                                 }
2394                                 fprintf(out, "%s %s %c%u:%u\n", mod->modname,
2395                                         devname, type, major, minor);
2396                         } else
2397                                 ERR("Module '%s' has devname (%s) but "
2398                                     "lacks major and minor information. "
2399                                     "Ignoring.\n", mod->modname, devname);
2400                 }
2401         }
2402
2403         return 0;
2404 }
2405
2406 static int output_builtin_alias_bin(struct depmod *depmod, FILE *out)
2407 {
2408         int ret = 0, count = 0;
2409         struct index_node *idx;
2410         struct kmod_list *l, *builtin = NULL;
2411
2412         if (out == stdout)
2413                 return 0;
2414
2415         idx = index_create();
2416         if (idx == NULL)
2417                 return -ENOMEM;
2418
2419         ret = kmod_module_get_builtin(depmod->ctx, &builtin);
2420         if (ret < 0) {
2421                 if (ret == -ENOENT)
2422                         ret = 0;
2423                 goto out;
2424         }
2425
2426         kmod_list_foreach(l, builtin) {
2427                 struct kmod_list *ll, *info_list = NULL;
2428                 struct kmod_module *mod = l->data;
2429                 const char *modname = kmod_module_get_name(mod);
2430
2431                 ret = kmod_module_get_info(mod, &info_list);
2432                 if (ret < 0)
2433                         goto out;
2434
2435                 kmod_list_foreach(ll, info_list) {
2436                         char alias[PATH_MAX];
2437                         const char *key = kmod_module_info_get_key(ll);
2438                         const char *value = kmod_module_info_get_value(ll);
2439
2440                         if (!streq(key, "alias"))
2441                                 continue;
2442
2443                         alias[0] = '\0';
2444                         if (alias_normalize(value, alias, NULL) < 0) {
2445                                 WRN("Unmatched bracket in %s\n", value);
2446                                 continue;
2447                         }
2448
2449                         index_insert(idx, alias, modname, 0);
2450                 }
2451
2452                 kmod_module_info_free_list(info_list);
2453
2454                 index_insert(idx, modname, modname, 0);
2455                 count++;
2456         }
2457
2458 out:
2459         /* do not bother writing the index if we are going to discard it */
2460         if (!ret)
2461                 index_write(idx, out);
2462
2463         if (builtin)
2464                 kmod_module_unref_list(builtin);
2465
2466         index_destroy(idx);
2467
2468         return ret;
2469 }
2470
2471 static int depmod_output(struct depmod *depmod, FILE *out)
2472 {
2473         static const struct depfile {
2474                 const char *name;
2475                 int (*cb)(struct depmod *depmod, FILE *out);
2476         } *itr, depfiles[] = {
2477                 { "modules.dep", output_deps },
2478                 { "modules.dep.bin", output_deps_bin },
2479                 { "modules.alias", output_aliases },
2480                 { "modules.alias.bin", output_aliases_bin },
2481                 { "modules.softdep", output_softdeps },
2482                 { "modules.symbols", output_symbols },
2483                 { "modules.symbols.bin", output_symbols_bin },
2484                 { "modules.builtin.bin", output_builtin_bin },
2485                 { "modules.builtin.alias.bin", output_builtin_alias_bin },
2486                 { "modules.devname", output_devname },
2487                 { }
2488         };
2489         const char *dname = depmod->cfg->dirname;
2490         int dfd, err = 0;
2491         struct timeval tv;
2492
2493         gettimeofday(&tv, NULL);
2494
2495         if (out != NULL)
2496                 dfd = -1;
2497         else {
2498                 dfd = open(dname, O_RDONLY);
2499                 if (dfd < 0) {
2500                         err = -errno;
2501                         CRIT("could not open directory %s: %m\n", dname);
2502                         return err;
2503                 }
2504         }
2505
2506         for (itr = depfiles; itr->name != NULL; itr++) {
2507                 FILE *fp = out;
2508                 char tmp[NAME_MAX] = "";
2509                 int r, ferr;
2510
2511                 if (fp == NULL) {
2512                         int flags = O_CREAT | O_EXCL | O_WRONLY;
2513                         int mode = 0644;
2514                         int fd;
2515
2516                         snprintf(tmp, sizeof(tmp), "%s.%i.%li.%li", itr->name, getpid(),
2517                                         tv.tv_usec, tv.tv_sec);
2518                         fd = openat(dfd, tmp, flags, mode);
2519                         if (fd < 0) {
2520                                 ERR("openat(%s, %s, %o, %o): %m\n",
2521                                     dname, tmp, flags, mode);
2522                                 continue;
2523                         }
2524                         fp = fdopen(fd, "wb");
2525                         if (fp == NULL) {
2526                                 ERR("fdopen(%d=%s/%s): %m\n", fd, dname, tmp);
2527                                 close(fd);
2528                                 continue;
2529                         }
2530                 }
2531
2532                 r = itr->cb(depmod, fp);
2533                 if (fp == out)
2534                         continue;
2535
2536                 ferr = ferror(fp) | fclose(fp);
2537
2538                 if (r < 0) {
2539                         if (unlinkat(dfd, tmp, 0) != 0)
2540                                 ERR("unlinkat(%s, %s): %m\n", dname, tmp);
2541
2542                         ERR("Could not write index '%s': %s\n", itr->name,
2543                                                                 strerror(-r));
2544                         err = -errno;
2545                         break;
2546                 }
2547
2548                 if (renameat(dfd, tmp, dfd, itr->name) != 0) {
2549                         err = -errno;
2550                         CRIT("renameat(%s, %s, %s, %s): %m\n",
2551                                         dname, tmp, dname, itr->name);
2552                         break;
2553                 }
2554
2555                 if (ferr) {
2556                         err = -ENOSPC;
2557                         ERR("Could not create index '%s'. Output is truncated: %s\n",
2558                                                 itr->name, strerror(-err));
2559                         break;
2560                 }
2561         }
2562
2563         if (dfd >= 0)
2564                 close(dfd);
2565
2566         return err;
2567 }
2568
2569 static void depmod_add_fake_syms(struct depmod *depmod)
2570 {
2571         /* __this_module is magic inserted by kernel loader. */
2572         depmod_symbol_add(depmod, "__this_module", true, 0, NULL);
2573         /* On S390, this is faked up too */
2574         depmod_symbol_add(depmod, "_GLOBAL_OFFSET_TABLE_", true, 0, NULL);
2575         /* On PowerPC64 ABIv2, .TOC. is more or less _GLOBAL_OFFSET_TABLE_ */
2576         if (!depmod_symbol_find(depmod, "TOC."))
2577                 depmod_symbol_add(depmod, "TOC.", true, 0, NULL);
2578 }
2579
2580 static int depmod_load_symvers(struct depmod *depmod, const char *filename)
2581 {
2582         char line[10240];
2583         FILE *fp;
2584         unsigned int linenum = 0;
2585
2586         fp = fopen(filename, "r");
2587         if (fp == NULL) {
2588                 int err = -errno;
2589                 DBG("load symvers: %s: %m\n", filename);
2590                 return err;
2591         }
2592         DBG("load symvers: %s\n", filename);
2593
2594         /* eg. "0xb352177e\tfind_first_bit\tvmlinux\tEXPORT_SYMBOL" */
2595         while (fgets(line, sizeof(line), fp) != NULL) {
2596                 const char *ver, *sym, *where;
2597                 char *verend;
2598                 uint64_t crc;
2599
2600                 linenum++;
2601
2602                 ver = strtok(line, " \t");
2603                 sym = strtok(NULL, " \t");
2604                 where = strtok(NULL, " \t");
2605                 if (!ver || !sym || !where)
2606                         continue;
2607
2608                 if (!streq(where, "vmlinux"))
2609                         continue;
2610
2611                 crc = strtoull(ver, &verend, 16);
2612                 if (verend[0] != '\0') {
2613                         ERR("%s:%u Invalid symbol version %s: %m\n",
2614                             filename, linenum, ver);
2615                         continue;
2616                 }
2617
2618                 depmod_symbol_add(depmod, sym, false, crc, NULL);
2619         }
2620         depmod_add_fake_syms(depmod);
2621
2622         DBG("loaded symvers: %s\n", filename);
2623
2624         fclose(fp);
2625         return 0;
2626 }
2627
2628 static int depmod_load_system_map(struct depmod *depmod, const char *filename)
2629 {
2630         const char ksymstr[] = "__ksymtab_";
2631         const size_t ksymstr_len = sizeof(ksymstr) - 1;
2632         char line[10240];
2633         FILE *fp;
2634         unsigned int linenum = 0;
2635
2636         fp = fopen(filename, "r");
2637         if (fp == NULL) {
2638                 int err = -errno;
2639                 DBG("load System.map: %s: %m\n", filename);
2640                 return err;
2641         }
2642         DBG("load System.map: %s\n", filename);
2643
2644         /* eg. c0294200 R __ksymtab_devfs_alloc_devnum */
2645         while (fgets(line, sizeof(line), fp) != NULL) {
2646                 char *p, *end;
2647
2648                 linenum++;
2649
2650                 p = strchr(line, ' ');
2651                 if (p == NULL)
2652                         goto invalid_syntax;
2653                 p++;
2654                 p = strchr(p, ' ');
2655                 if (p == NULL)
2656                         goto invalid_syntax;
2657                 p++;
2658
2659                 /* skip prefix */
2660                 if (p[0] == depmod->cfg->sym_prefix)
2661                         p++;
2662
2663                 /* Covers gpl-only and normal symbols. */
2664                 if (strncmp(p, ksymstr, ksymstr_len) != 0)
2665                         continue;
2666
2667                 end = strchr(p, '\n');
2668                 if (end != NULL)
2669                         *end = '\0';
2670
2671                 depmod_symbol_add(depmod, p + ksymstr_len, true, 0, NULL);
2672                 continue;
2673
2674         invalid_syntax:
2675                 ERR("%s:%u: invalid line: %s\n", filename, linenum, line);
2676         }
2677         depmod_add_fake_syms(depmod);
2678
2679         DBG("loaded System.map: %s\n", filename);
2680
2681         fclose(fp);
2682         return 0;
2683 }
2684
2685
2686 static int depfile_up_to_date_dir(DIR *d, time_t mtime, size_t baselen, char *path)
2687 {
2688         struct dirent *de;
2689         int err = 1, dfd = dirfd(d);
2690
2691         while ((de = readdir(d)) != NULL) {
2692                 const char *name = de->d_name;
2693                 size_t namelen;
2694                 struct stat st;
2695
2696                 if (name[0] == '.' && (name[1] == '\0' ||
2697                                        (name[1] == '.' && name[2] == '\0')))
2698                         continue;
2699                 if (streq(name, "build") || streq(name, "source"))
2700                         continue;
2701                 namelen = strlen(name);
2702                 if (baselen + namelen + 2 >= PATH_MAX) {
2703                         path[baselen] = '\0';
2704                         ERR("path is too long %s%s\n", path, name);
2705                         continue;
2706                 }
2707
2708                 if (fstatat(dfd, name, &st, 0) < 0) {
2709                         ERR("fstatat(%d, %s): %m\n", dfd, name);
2710                         continue;
2711                 }
2712
2713                 if (S_ISDIR(st.st_mode)) {
2714                         int fd;
2715                         DIR *subdir;
2716                         memcpy(path + baselen, name, namelen + 1);
2717                         if (baselen + namelen + 2 + NAME_MAX >= PATH_MAX) {
2718                                 ERR("directory path is too long %s\n", path);
2719                                 continue;
2720                         }
2721                         fd = openat(dfd, name, O_RDONLY);
2722                         if (fd < 0) {
2723                                 ERR("openat(%d, %s, O_RDONLY): %m\n",
2724                                     dfd, name);
2725                                 continue;
2726                         }
2727                         subdir = fdopendir(fd);
2728                         if (subdir == NULL) {
2729                                 ERR("fdopendir(%d): %m\n", fd);
2730                                 close(fd);
2731                                 continue;
2732                         }
2733                         path[baselen + namelen] = '/';
2734                         path[baselen + namelen + 1] = '\0';
2735                         err = depfile_up_to_date_dir(subdir, mtime,
2736                                                      baselen + namelen + 1,
2737                                                      path);
2738                         closedir(subdir);
2739                 } else if (S_ISREG(st.st_mode)) {
2740                         if (!path_ends_with_kmod_ext(name, namelen))
2741                                 continue;
2742
2743                         memcpy(path + baselen, name, namelen + 1);
2744                         err = st.st_mtime <= mtime;
2745                         if (err == 0) {
2746                                 DBG("%s %"PRIu64" is newer than %"PRIu64"\n",
2747                                     path, (uint64_t)st.st_mtime,
2748                                     (uint64_t)mtime);
2749                         }
2750                 } else {
2751                         ERR("unsupported file type %s: %o\n",
2752                             path, st.st_mode & S_IFMT);
2753                         continue;
2754                 }
2755
2756                 if (err == 0)
2757                         break; /* outdated! */
2758                 else if (err < 0) {
2759                         path[baselen + namelen] = '\0';
2760                         ERR("failed %s: %s\n", path, strerror(-err));
2761                         err = 1; /* ignore errors */
2762                 }
2763         }
2764
2765         return err;
2766 }
2767
2768 /* uptodate: 1, outdated: 0, errors < 0 */
2769 static int depfile_up_to_date(const char *dirname)
2770 {
2771         char path[PATH_MAX];
2772         DIR *d = opendir(dirname);
2773         struct stat st;
2774         size_t baselen;
2775         int err;
2776         if (d == NULL) {
2777                 err = -errno;
2778                 ERR("could not open directory %s: %m\n", dirname);
2779                 return err;
2780         }
2781
2782         if (fstatat(dirfd(d), "modules.dep", &st, 0) != 0) {
2783                 err = -errno;
2784                 ERR("could not fstatat(%s, modules.dep): %m\n", dirname);
2785                 closedir(d);
2786                 return err;
2787         }
2788
2789         baselen = strlen(dirname);
2790         memcpy(path, dirname, baselen);
2791         path[baselen] = '/';
2792         baselen++;
2793         path[baselen] = '\0';
2794
2795         err = depfile_up_to_date_dir(d, st.st_mtime, baselen, path);
2796         closedir(d);
2797         return err;
2798 }
2799
2800 static int is_version_number(const char *version)
2801 {
2802         unsigned int d1, d2;
2803         return (sscanf(version, "%u.%u", &d1, &d2) == 2);
2804 }
2805
2806 static int do_depmod(int argc, char *argv[])
2807 {
2808         FILE *out = NULL;
2809         int err = 0, all = 0, maybe_all = 0, n_config_paths = 0;
2810         _cleanup_free_ char *root = NULL;
2811         _cleanup_free_ const char **config_paths = NULL;
2812         const char *system_map = NULL;
2813         const char *module_symvers = NULL;
2814         const char *null_kmod_config = NULL;
2815         struct utsname un;
2816         struct kmod_ctx *ctx = NULL;
2817         struct cfg cfg;
2818         struct depmod depmod;
2819
2820         memset(&cfg, 0, sizeof(cfg));
2821         memset(&depmod, 0, sizeof(depmod));
2822
2823         for (;;) {
2824                 int c, idx = 0;
2825                 c = getopt_long(argc, argv, cmdopts_s, cmdopts, &idx);
2826                 if (c == -1)
2827                         break;
2828                 switch (c) {
2829                 case 'a':
2830                         all = 1;
2831                         break;
2832                 case 'A':
2833                         maybe_all = 1;
2834                         break;
2835                 case 'b':
2836                         if (root)
2837                                 free(root);
2838                         root = path_make_absolute_cwd(optarg);
2839                         break;
2840                 case 'C': {
2841                         size_t bytes = sizeof(char *) * (n_config_paths + 2);
2842                         void *tmp = realloc(config_paths, bytes);
2843                         if (!tmp) {
2844                                 fputs("Error: out-of-memory\n", stderr);
2845                                 goto cmdline_failed;
2846                         }
2847                         config_paths = tmp;
2848                         config_paths[n_config_paths] = optarg;
2849                         n_config_paths++;
2850                         config_paths[n_config_paths] = NULL;
2851                         break;
2852                 }
2853                 case 'E':
2854                         module_symvers = optarg;
2855                         cfg.check_symvers = 1;
2856                         break;
2857                 case 'F':
2858                         system_map = optarg;
2859                         break;
2860                 case 'e':
2861                         cfg.print_unknown = 1;
2862                         break;
2863                 case 'v':
2864                         verbose++;
2865                         break;
2866                 case 'n':
2867                         out = stdout;
2868                         break;
2869                 case 'P':
2870                         if (optarg[1] != '\0') {
2871                                 CRIT("-P only takes a single char\n");
2872                                 goto cmdline_failed;
2873                         }
2874                         cfg.sym_prefix = optarg[0];
2875                         break;
2876                 case 'w':
2877                         cfg.warn_dups = 1;
2878                         break;
2879                 case 'u':
2880                 case 'q':
2881                 case 'r':
2882                 case 'm':
2883                         if (idx > 0)
2884                                 WRN("Ignored deprecated option --%s\n",
2885                                     cmdopts[idx].name);
2886                         else
2887                                 WRN("Ignored deprecated option -%c\n", c);
2888
2889                         break;
2890                 case 'h':
2891                         help();
2892                         return EXIT_SUCCESS;
2893                 case 'V':
2894                         puts(PACKAGE " version " VERSION);
2895                         puts(KMOD_FEATURES);
2896                         return EXIT_SUCCESS;
2897                 case '?':
2898                         goto cmdline_failed;
2899                 default:
2900                         ERR("unexpected getopt_long() value '%c'.\n", c);
2901                         goto cmdline_failed;
2902                 }
2903         }
2904
2905         if (optind < argc) {
2906                 if (!is_version_number(argv[optind])) {
2907                         ERR("Bad version passed %s\n", argv[optind]);
2908                         goto cmdline_failed;
2909                 }
2910                 cfg.kversion = argv[optind];
2911                 optind++;
2912         } else {
2913                 if (uname(&un) < 0) {
2914                         CRIT("uname() failed: %s\n", strerror(errno));
2915                         goto cmdline_failed;
2916                 }
2917                 cfg.kversion = un.release;
2918         }
2919
2920         cfg.dirnamelen = snprintf(cfg.dirname, PATH_MAX,
2921                                   "%s/lib/modules/%s",
2922                                   root == NULL ? "" : root, cfg.kversion);
2923
2924         if (optind == argc)
2925                 all = 1;
2926
2927         if (maybe_all) {
2928                 if (out == stdout)
2929                         goto done;
2930                 /* ignore up-to-date errors (< 0) */
2931                 if (depfile_up_to_date(cfg.dirname) == 1)
2932                         goto done;
2933                 all = 1;
2934         }
2935
2936         ctx = kmod_new(cfg.dirname, &null_kmod_config);
2937         if (ctx == NULL) {
2938                 CRIT("kmod_new(\"%s\", {NULL}) failed: %m\n", cfg.dirname);
2939                 goto cmdline_failed;
2940         }
2941
2942         log_setup_kmod_log(ctx, verbose);
2943
2944         err = depmod_init(&depmod, &cfg, ctx);
2945         if (err < 0) {
2946                 CRIT("depmod_init: %s\n", strerror(-err));
2947                 goto depmod_init_failed;
2948         }
2949         ctx = NULL; /* owned by depmod */
2950
2951         if (module_symvers != NULL) {
2952                 err = depmod_load_symvers(&depmod, module_symvers);
2953                 if (err < 0) {
2954                         CRIT("could not load %s: %s\n", module_symvers,
2955                              strerror(-err));
2956                         goto cmdline_failed;
2957                 }
2958         } else if (system_map != NULL) {
2959                 err = depmod_load_system_map(&depmod, system_map);
2960                 if (err < 0) {
2961                         CRIT("could not load %s: %s\n", system_map,
2962                              strerror(-err));
2963                         goto cmdline_failed;
2964                 }
2965         } else if (cfg.print_unknown) {
2966                 WRN("-e needs -E or -F\n");
2967                 cfg.print_unknown = 0;
2968         }
2969
2970         if (all) {
2971                 err = cfg_load(&cfg, config_paths);
2972                 if (err < 0) {
2973                         CRIT("could not load configuration files\n");
2974                         goto cmdline_modules_failed;
2975                 }
2976                 err = depmod_modules_search(&depmod);
2977                 if (err < 0) {
2978                         CRIT("could not search modules: %s\n", strerror(-err));
2979                         goto cmdline_modules_failed;
2980                 }
2981         } else {
2982                 int i;
2983
2984                 for (i = optind; i < argc; i++) {
2985                         const char *path = argv[i];
2986                         struct kmod_module *mod;
2987
2988                         if (path[0] != '/') {
2989                                 CRIT("%s: not absolute path.\n", path);
2990                                 goto cmdline_modules_failed;
2991                         }
2992
2993                         err = kmod_module_new_from_path(depmod.ctx, path, &mod);
2994                         if (err < 0) {
2995                                 CRIT("could not create module %s: %s\n",
2996                                      path, strerror(-err));
2997                                 goto cmdline_modules_failed;
2998                         }
2999
3000                         err = depmod_module_add(&depmod, mod);
3001                         if (err < 0) {
3002                                 CRIT("could not add module %s: %s\n",
3003                                      path, strerror(-err));
3004                                 kmod_module_unref(mod);
3005                                 goto cmdline_modules_failed;
3006                         }
3007                 }
3008         }
3009
3010         err = depmod_modules_build_array(&depmod);
3011         if (err < 0) {
3012                 CRIT("could not build module array: %s\n",
3013                      strerror(-err));
3014                 goto cmdline_modules_failed;
3015         }
3016
3017         depmod_modules_sort(&depmod);
3018         err = depmod_load(&depmod);
3019         if (err < 0)
3020                 goto cmdline_modules_failed;
3021
3022         err = depmod_output(&depmod, out);
3023
3024 done:
3025         depmod_shutdown(&depmod);
3026         cfg_free(&cfg);
3027         return err >= 0 ? EXIT_SUCCESS : EXIT_FAILURE;
3028
3029 cmdline_modules_failed:
3030         depmod_shutdown(&depmod);
3031 depmod_init_failed:
3032         if (ctx != NULL)
3033                 kmod_unref(ctx);
3034 cmdline_failed:
3035         cfg_free(&cfg);
3036         return EXIT_FAILURE;
3037 }
3038
3039 const struct kmod_cmd kmod_cmd_compat_depmod = {
3040         .name = "depmod",
3041         .cmd = do_depmod,
3042         .help = "compat depmod command",
3043 };