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 (at) 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 depmod_output(struct depmod *depmod, FILE *out) 2406 { 2407 static const struct depfile { 2408 const char *name; 2409 int (*cb)(struct depmod *depmod, FILE *out); 2410 } *itr, depfiles[] = { 2411 { "modules.dep", output_deps }, 2412 { "modules.dep.bin", output_deps_bin }, 2413 { "modules.alias", output_aliases }, 2414 { "modules.alias.bin", output_aliases_bin }, 2415 { "modules.softdep", output_softdeps }, 2416 { "modules.symbols", output_symbols }, 2417 { "modules.symbols.bin", output_symbols_bin }, 2418 { "modules.builtin.bin", output_builtin_bin }, 2419 { "modules.devname", output_devname }, 2420 { } 2421 }; 2422 const char *dname = depmod->cfg->dirname; 2423 int dfd, err = 0; 2424 struct timeval tv; 2425 2426 gettimeofday(&tv, NULL); 2427 2428 if (out != NULL) 2429 dfd = -1; 2430 else { 2431 dfd = open(dname, O_RDONLY); 2432 if (dfd < 0) { 2433 err = -errno; 2434 CRIT("could not open directory %s: %m\n", dname); 2435 return err; 2436 } 2437 } 2438 2439 for (itr = depfiles; itr->name != NULL; itr++) { 2440 FILE *fp = out; 2441 char tmp[NAME_MAX] = ""; 2442 int r, ferr; 2443 2444 if (fp == NULL) { 2445 int flags = O_CREAT | O_EXCL | O_WRONLY; 2446 int mode = 0644; 2447 int fd; 2448 2449 snprintf(tmp, sizeof(tmp), "%s.%i.%li.%li", itr->name, getpid(), 2450 tv.tv_usec, tv.tv_sec); 2451 fd = openat(dfd, tmp, flags, mode); 2452 if (fd < 0) { 2453 ERR("openat(%s, %s, %o, %o): %m\n", 2454 dname, tmp, flags, mode); 2455 continue; 2456 } 2457 fp = fdopen(fd, "wb"); 2458 if (fp == NULL) { 2459 ERR("fdopen(%d=%s/%s): %m\n", fd, dname, tmp); 2460 close(fd); 2461 continue; 2462 } 2463 } 2464 2465 r = itr->cb(depmod, fp); 2466 if (fp == out) 2467 continue; 2468 2469 ferr = ferror(fp) | fclose(fp); 2470 2471 if (r < 0) { 2472 if (unlinkat(dfd, tmp, 0) != 0) 2473 ERR("unlinkat(%s, %s): %m\n", dname, tmp); 2474 2475 ERR("Could not write index '%s': %s\n", itr->name, 2476 strerror(-r)); 2477 err = -errno; 2478 break; 2479 } 2480 2481 if (renameat(dfd, tmp, dfd, itr->name) != 0) { 2482 err = -errno; 2483 CRIT("renameat(%s, %s, %s, %s): %m\n", 2484 dname, tmp, dname, itr->name); 2485 break; 2486 } 2487 2488 if (ferr) { 2489 err = -ENOSPC; 2490 ERR("Could not create index '%s'. Output is truncated: %s\n", 2491 itr->name, strerror(-err)); 2492 break; 2493 } 2494 } 2495 2496 if (dfd >= 0) 2497 close(dfd); 2498 2499 return err; 2500 } 2501 2502 static void depmod_add_fake_syms(struct depmod *depmod) 2503 { 2504 /* __this_module is magic inserted by kernel loader. */ 2505 depmod_symbol_add(depmod, "__this_module", true, 0, NULL); 2506 /* On S390, this is faked up too */ 2507 depmod_symbol_add(depmod, "_GLOBAL_OFFSET_TABLE_", true, 0, NULL); 2508 /* On PowerPC64 ABIv2, .TOC. is more or less _GLOBAL_OFFSET_TABLE_ */ 2509 if (!depmod_symbol_find(depmod, "TOC.")) 2510 depmod_symbol_add(depmod, "TOC.", true, 0, NULL); 2511 } 2512 2513 static int depmod_load_symvers(struct depmod *depmod, const char *filename) 2514 { 2515 char line[10240]; 2516 FILE *fp; 2517 unsigned int linenum = 0; 2518 2519 fp = fopen(filename, "r"); 2520 if (fp == NULL) { 2521 int err = -errno; 2522 DBG("load symvers: %s: %m\n", filename); 2523 return err; 2524 } 2525 DBG("load symvers: %s\n", filename); 2526 2527 /* eg. "0xb352177e\tfind_first_bit\tvmlinux\tEXPORT_SYMBOL" */ 2528 while (fgets(line, sizeof(line), fp) != NULL) { 2529 const char *ver, *sym, *where; 2530 char *verend; 2531 uint64_t crc; 2532 2533 linenum++; 2534 2535 ver = strtok(line, " \t"); 2536 sym = strtok(NULL, " \t"); 2537 where = strtok(NULL, " \t"); 2538 if (!ver || !sym || !where) 2539 continue; 2540 2541 if (!streq(where, "vmlinux")) 2542 continue; 2543 2544 crc = strtoull(ver, &verend, 16); 2545 if (verend[0] != '\0') { 2546 ERR("%s:%u Invalid symbol version %s: %m\n", 2547 filename, linenum, ver); 2548 continue; 2549 } 2550 2551 depmod_symbol_add(depmod, sym, false, crc, NULL); 2552 } 2553 depmod_add_fake_syms(depmod); 2554 2555 DBG("loaded symvers: %s\n", filename); 2556 2557 fclose(fp); 2558 return 0; 2559 } 2560 2561 static int depmod_load_system_map(struct depmod *depmod, const char *filename) 2562 { 2563 const char ksymstr[] = "__ksymtab_"; 2564 const size_t ksymstr_len = sizeof(ksymstr) - 1; 2565 char line[10240]; 2566 FILE *fp; 2567 unsigned int linenum = 0; 2568 2569 fp = fopen(filename, "r"); 2570 if (fp == NULL) { 2571 int err = -errno; 2572 DBG("load System.map: %s: %m\n", filename); 2573 return err; 2574 } 2575 DBG("load System.map: %s\n", filename); 2576 2577 /* eg. c0294200 R __ksymtab_devfs_alloc_devnum */ 2578 while (fgets(line, sizeof(line), fp) != NULL) { 2579 char *p, *end; 2580 2581 linenum++; 2582 2583 p = strchr(line, ' '); 2584 if (p == NULL) 2585 goto invalid_syntax; 2586 p++; 2587 p = strchr(p, ' '); 2588 if (p == NULL) 2589 goto invalid_syntax; 2590 p++; 2591 2592 /* skip prefix */ 2593 if (p[0] == depmod->cfg->sym_prefix) 2594 p++; 2595 2596 /* Covers gpl-only and normal symbols. */ 2597 if (strncmp(p, ksymstr, ksymstr_len) != 0) 2598 continue; 2599 2600 end = strchr(p, '\n'); 2601 if (end != NULL) 2602 *end = '\0'; 2603 2604 depmod_symbol_add(depmod, p + ksymstr_len, true, 0, NULL); 2605 continue; 2606 2607 invalid_syntax: 2608 ERR("%s:%u: invalid line: %s\n", filename, linenum, line); 2609 } 2610 depmod_add_fake_syms(depmod); 2611 2612 DBG("loaded System.map: %s\n", filename); 2613 2614 fclose(fp); 2615 return 0; 2616 } 2617 2618 2619 static int depfile_up_to_date_dir(DIR *d, time_t mtime, size_t baselen, char *path) 2620 { 2621 struct dirent *de; 2622 int err = 1, dfd = dirfd(d); 2623 2624 while ((de = readdir(d)) != NULL) { 2625 const char *name = de->d_name; 2626 size_t namelen; 2627 struct stat st; 2628 2629 if (name[0] == '.' && (name[1] == '\0' || 2630 (name[1] == '.' && name[2] == '\0'))) 2631 continue; 2632 if (streq(name, "build") || streq(name, "source")) 2633 continue; 2634 namelen = strlen(name); 2635 if (baselen + namelen + 2 >= PATH_MAX) { 2636 path[baselen] = '\0'; 2637 ERR("path is too long %s%s\n", path, name); 2638 continue; 2639 } 2640 2641 if (fstatat(dfd, name, &st, 0) < 0) { 2642 ERR("fstatat(%d, %s): %m\n", dfd, name); 2643 continue; 2644 } 2645 2646 if (S_ISDIR(st.st_mode)) { 2647 int fd; 2648 DIR *subdir; 2649 memcpy(path + baselen, name, namelen + 1); 2650 if (baselen + namelen + 2 + NAME_MAX >= PATH_MAX) { 2651 ERR("directory path is too long %s\n", path); 2652 continue; 2653 } 2654 fd = openat(dfd, name, O_RDONLY); 2655 if (fd < 0) { 2656 ERR("openat(%d, %s, O_RDONLY): %m\n", 2657 dfd, name); 2658 continue; 2659 } 2660 subdir = fdopendir(fd); 2661 if (subdir == NULL) { 2662 ERR("fdopendir(%d): %m\n", fd); 2663 close(fd); 2664 continue; 2665 } 2666 path[baselen + namelen] = '/'; 2667 path[baselen + namelen + 1] = '\0'; 2668 err = depfile_up_to_date_dir(subdir, mtime, 2669 baselen + namelen + 1, 2670 path); 2671 closedir(subdir); 2672 } else if (S_ISREG(st.st_mode)) { 2673 if (!path_ends_with_kmod_ext(name, namelen)) 2674 continue; 2675 2676 memcpy(path + baselen, name, namelen + 1); 2677 err = st.st_mtime <= mtime; 2678 if (err == 0) { 2679 DBG("%s %"PRIu64" is newer than %"PRIu64"\n", 2680 path, (uint64_t)st.st_mtime, 2681 (uint64_t)mtime); 2682 } 2683 } else { 2684 ERR("unsupported file type %s: %o\n", 2685 path, st.st_mode & S_IFMT); 2686 continue; 2687 } 2688 2689 if (err == 0) 2690 break; /* outdated! */ 2691 else if (err < 0) { 2692 path[baselen + namelen] = '\0'; 2693 ERR("failed %s: %s\n", path, strerror(-err)); 2694 err = 1; /* ignore errors */ 2695 } 2696 } 2697 2698 return err; 2699 } 2700 2701 /* uptodate: 1, outdated: 0, errors < 0 */ 2702 static int depfile_up_to_date(const char *dirname) 2703 { 2704 char path[PATH_MAX]; 2705 DIR *d = opendir(dirname); 2706 struct stat st; 2707 size_t baselen; 2708 int err; 2709 if (d == NULL) { 2710 err = -errno; 2711 ERR("could not open directory %s: %m\n", dirname); 2712 return err; 2713 } 2714 2715 if (fstatat(dirfd(d), "modules.dep", &st, 0) != 0) { 2716 err = -errno; 2717 ERR("could not fstatat(%s, modules.dep): %m\n", dirname); 2718 closedir(d); 2719 return err; 2720 } 2721 2722 baselen = strlen(dirname); 2723 memcpy(path, dirname, baselen); 2724 path[baselen] = '/'; 2725 baselen++; 2726 path[baselen] = '\0'; 2727 2728 err = depfile_up_to_date_dir(d, st.st_mtime, baselen, path); 2729 closedir(d); 2730 return err; 2731 } 2732 2733 static int is_version_number(const char *version) 2734 { 2735 unsigned int d1, d2; 2736 return (sscanf(version, "%u.%u", &d1, &d2) == 2); 2737 } 2738 2739 static int do_depmod(int argc, char *argv[]) 2740 { 2741 FILE *out = NULL; 2742 int err = 0, all = 0, maybe_all = 0, n_config_paths = 0; 2743 _cleanup_free_ char *root = NULL; 2744 _cleanup_free_ const char **config_paths = NULL; 2745 const char *system_map = NULL; 2746 const char *module_symvers = NULL; 2747 const char *null_kmod_config = NULL; 2748 struct utsname un; 2749 struct kmod_ctx *ctx = NULL; 2750 struct cfg cfg; 2751 struct depmod depmod; 2752 2753 memset(&cfg, 0, sizeof(cfg)); 2754 memset(&depmod, 0, sizeof(depmod)); 2755 2756 for (;;) { 2757 int c, idx = 0; 2758 c = getopt_long(argc, argv, cmdopts_s, cmdopts, &idx); 2759 if (c == -1) 2760 break; 2761 switch (c) { 2762 case 'a': 2763 all = 1; 2764 break; 2765 case 'A': 2766 maybe_all = 1; 2767 break; 2768 case 'b': 2769 if (root) 2770 free(root); 2771 root = path_make_absolute_cwd(optarg); 2772 break; 2773 case 'C': { 2774 size_t bytes = sizeof(char *) * (n_config_paths + 2); 2775 void *tmp = realloc(config_paths, bytes); 2776 if (!tmp) { 2777 fputs("Error: out-of-memory\n", stderr); 2778 goto cmdline_failed; 2779 } 2780 config_paths = tmp; 2781 config_paths[n_config_paths] = optarg; 2782 n_config_paths++; 2783 config_paths[n_config_paths] = NULL; 2784 break; 2785 } 2786 case 'E': 2787 module_symvers = optarg; 2788 cfg.check_symvers = 1; 2789 break; 2790 case 'F': 2791 system_map = optarg; 2792 break; 2793 case 'e': 2794 cfg.print_unknown = 1; 2795 break; 2796 case 'v': 2797 verbose++; 2798 break; 2799 case 'n': 2800 out = stdout; 2801 break; 2802 case 'P': 2803 if (optarg[1] != '\0') { 2804 CRIT("-P only takes a single char\n"); 2805 goto cmdline_failed; 2806 } 2807 cfg.sym_prefix = optarg[0]; 2808 break; 2809 case 'w': 2810 cfg.warn_dups = 1; 2811 break; 2812 case 'u': 2813 case 'q': 2814 case 'r': 2815 case 'm': 2816 if (idx > 0) 2817 WRN("Ignored deprecated option --%s\n", 2818 cmdopts[idx].name); 2819 else 2820 WRN("Ignored deprecated option -%c\n", c); 2821 2822 break; 2823 case 'h': 2824 help(); 2825 return EXIT_SUCCESS; 2826 case 'V': 2827 puts(PACKAGE " version " VERSION); 2828 puts(KMOD_FEATURES); 2829 return EXIT_SUCCESS; 2830 case '?': 2831 goto cmdline_failed; 2832 default: 2833 ERR("unexpected getopt_long() value '%c'.\n", c); 2834 goto cmdline_failed; 2835 } 2836 } 2837 2838 if (optind < argc) { 2839 if (!is_version_number(argv[optind])) { 2840 ERR("Bad version passed %s\n", argv[optind]); 2841 goto cmdline_failed; 2842 } 2843 cfg.kversion = argv[optind]; 2844 optind++; 2845 } else { 2846 if (uname(&un) < 0) { 2847 CRIT("uname() failed: %s\n", strerror(errno)); 2848 goto cmdline_failed; 2849 } 2850 cfg.kversion = un.release; 2851 } 2852 2853 cfg.dirnamelen = snprintf(cfg.dirname, PATH_MAX, 2854 "%s/lib/modules/%s", 2855 root == NULL ? "" : root, cfg.kversion); 2856 2857 if (optind == argc) 2858 all = 1; 2859 2860 if (maybe_all) { 2861 if (out == stdout) 2862 goto done; 2863 /* ignore up-to-date errors (< 0) */ 2864 if (depfile_up_to_date(cfg.dirname) == 1) 2865 goto done; 2866 all = 1; 2867 } 2868 2869 ctx = kmod_new(cfg.dirname, &null_kmod_config); 2870 if (ctx == NULL) { 2871 CRIT("kmod_new(\"%s\", {NULL}) failed: %m\n", cfg.dirname); 2872 goto cmdline_failed; 2873 } 2874 2875 log_setup_kmod_log(ctx, verbose); 2876 2877 err = depmod_init(&depmod, &cfg, ctx); 2878 if (err < 0) { 2879 CRIT("depmod_init: %s\n", strerror(-err)); 2880 goto depmod_init_failed; 2881 } 2882 ctx = NULL; /* owned by depmod */ 2883 2884 if (module_symvers != NULL) { 2885 err = depmod_load_symvers(&depmod, module_symvers); 2886 if (err < 0) { 2887 CRIT("could not load %s: %s\n", module_symvers, 2888 strerror(-err)); 2889 goto cmdline_failed; 2890 } 2891 } else if (system_map != NULL) { 2892 err = depmod_load_system_map(&depmod, system_map); 2893 if (err < 0) { 2894 CRIT("could not load %s: %s\n", system_map, 2895 strerror(-err)); 2896 goto cmdline_failed; 2897 } 2898 } else if (cfg.print_unknown) { 2899 WRN("-e needs -E or -F\n"); 2900 cfg.print_unknown = 0; 2901 } 2902 2903 if (all) { 2904 err = cfg_load(&cfg, config_paths); 2905 if (err < 0) { 2906 CRIT("could not load configuration files\n"); 2907 goto cmdline_modules_failed; 2908 } 2909 err = depmod_modules_search(&depmod); 2910 if (err < 0) { 2911 CRIT("could not search modules: %s\n", strerror(-err)); 2912 goto cmdline_modules_failed; 2913 } 2914 } else { 2915 int i; 2916 2917 for (i = optind; i < argc; i++) { 2918 const char *path = argv[i]; 2919 struct kmod_module *mod; 2920 2921 if (path[0] != '/') { 2922 CRIT("%s: not absolute path.\n", path); 2923 goto cmdline_modules_failed; 2924 } 2925 2926 err = kmod_module_new_from_path(depmod.ctx, path, &mod); 2927 if (err < 0) { 2928 CRIT("could not create module %s: %s\n", 2929 path, strerror(-err)); 2930 goto cmdline_modules_failed; 2931 } 2932 2933 err = depmod_module_add(&depmod, mod); 2934 if (err < 0) { 2935 CRIT("could not add module %s: %s\n", 2936 path, strerror(-err)); 2937 kmod_module_unref(mod); 2938 goto cmdline_modules_failed; 2939 } 2940 } 2941 } 2942 2943 err = depmod_modules_build_array(&depmod); 2944 if (err < 0) { 2945 CRIT("could not build module array: %s\n", 2946 strerror(-err)); 2947 goto cmdline_modules_failed; 2948 } 2949 2950 depmod_modules_sort(&depmod); 2951 err = depmod_load(&depmod); 2952 if (err < 0) 2953 goto cmdline_modules_failed; 2954 2955 err = depmod_output(&depmod, out); 2956 2957 done: 2958 depmod_shutdown(&depmod); 2959 cfg_free(&cfg); 2960 return err >= 0 ? EXIT_SUCCESS : EXIT_FAILURE; 2961 2962 cmdline_modules_failed: 2963 depmod_shutdown(&depmod); 2964 depmod_init_failed: 2965 if (ctx != NULL) 2966 kmod_unref(ctx); 2967 cmdline_failed: 2968 cfg_free(&cfg); 2969 return EXIT_FAILURE; 2970 } 2971 2972 const struct kmod_cmd kmod_cmd_compat_depmod = { 2973 .name = "depmod", 2974 .cmd = do_depmod, 2975 .help = "compat depmod command", 2976 }; 2977