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