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