system/corennnnn
修订版 | b62a23e61bfd99080e8dc172a632e1aa9dfc2964 (tree) |
---|---|
时间 | 2016-09-29 12:28:58 |
作者 | Chih-Wei Huang <cwhuang@linu...> |
Commiter | Chih-Wei Huang |
ueventd: defer modules loading if explicitly listed
The patch extends the syntax of /etc/modules.blacklist.
The modules marked as deferred in this file will be loaded
after all other modules are loaded at coldboot stage.
@@ -111,6 +111,7 @@ struct module_alias_node { | ||
111 | 111 | |
112 | 112 | struct module_blacklist_node { |
113 | 113 | char *name; |
114 | + bool deferred; | |
114 | 115 | struct listnode list; |
115 | 116 | }; |
116 | 117 |
@@ -767,7 +768,7 @@ static void handle_generic_device_event(struct uevent *uevent) | ||
767 | 768 | uevent->major, uevent->minor, links); |
768 | 769 | } |
769 | 770 | |
770 | -static int is_module_blacklisted(const char *name) | |
771 | +static int is_module_blacklisted_or_deferred(const char *name, bool need_deferred) | |
771 | 772 | { |
772 | 773 | struct listnode *blklst_node; |
773 | 774 | struct module_blacklist_node *blacklist; |
@@ -782,7 +783,7 @@ static int is_module_blacklisted(const char *name) | ||
782 | 783 | list); |
783 | 784 | if (!strcmp(name, blacklist->name)) { |
784 | 785 | INFO("modules %s is blacklisted\n", name); |
785 | - ret = 1; | |
786 | + ret = blacklist->deferred ? (need_deferred ? 2 : 0) : 1; | |
786 | 787 | goto out; |
787 | 788 | } |
788 | 789 | } |
@@ -791,7 +792,7 @@ out: | ||
791 | 792 | return ret; |
792 | 793 | } |
793 | 794 | |
794 | -static int load_module_by_device_modalias(const char *id) | |
795 | +static int load_module_by_device_modalias(const char *id, bool need_deferred) | |
795 | 796 | { |
796 | 797 | struct listnode *alias_node; |
797 | 798 | struct module_alias_node *alias; |
@@ -804,8 +805,9 @@ static int load_module_by_device_modalias(const char *id) | ||
804 | 805 | if (fnmatch(alias->pattern, id, 0) == 0) { |
805 | 806 | INFO("trying to load module %s due to uevents\n", alias->name); |
806 | 807 | |
807 | - if (!is_module_blacklisted(alias->name)) { | |
808 | - if (insmod_by_dep(alias->name, "", NULL, 0, NULL)) { | |
808 | + ret = is_module_blacklisted_or_deferred(alias->name, need_deferred); | |
809 | + if (ret == 0) { | |
810 | + if ((ret = insmod_by_dep(alias->name, "", NULL, 0, NULL))) { | |
809 | 811 | /* cannot load module. try another one since |
810 | 812 | * there may be another match. |
811 | 813 | */ |
@@ -814,8 +816,9 @@ static int load_module_by_device_modalias(const char *id) | ||
814 | 816 | } else { |
815 | 817 | /* loading was successful */ |
816 | 818 | INFO("loaded module %s due to uevents\n", alias->name); |
817 | - ret = 0; | |
818 | 819 | } |
820 | + } else { | |
821 | + NOTICE("blacklisted module %s: %d\n", alias->name, ret); | |
819 | 822 | } |
820 | 823 | } |
821 | 824 | } |
@@ -839,7 +842,7 @@ static void handle_deferred_module_loading() | ||
839 | 842 | |
840 | 843 | if (alias && alias->pattern) { |
841 | 844 | INFO("deferred loading of module for %s\n", alias->pattern); |
842 | - load_module_by_device_modalias(alias->pattern); | |
845 | + load_module_by_device_modalias(alias->pattern, false); | |
843 | 846 | free(alias->pattern); |
844 | 847 | list_remove(node); |
845 | 848 | free(alias); |
@@ -857,7 +860,12 @@ int module_probe(const char *modalias) | ||
857 | 860 | return -1; |
858 | 861 | } |
859 | 862 | |
860 | - return modalias ? load_module_by_device_modalias(modalias) : -1; | |
863 | + return modalias ? load_module_by_device_modalias(modalias, false) : -1; | |
864 | +} | |
865 | + | |
866 | +static int is_booting(void) | |
867 | +{ | |
868 | + return access("/dev/.booting", F_OK) == 0; | |
861 | 869 | } |
862 | 870 | |
863 | 871 | static void handle_module_loading(const char *modalias) |
@@ -870,13 +878,13 @@ static void handle_module_loading(const char *modalias) | ||
870 | 878 | if (list_empty(&modules_aliases_map)) { |
871 | 879 | if (read_modules_aliases() == 0) { |
872 | 880 | read_modules_blacklist(); |
873 | - handle_deferred_module_loading(); | |
874 | 881 | } |
875 | 882 | } |
876 | 883 | |
877 | 884 | if (!modalias) return; |
878 | 885 | |
879 | - if (list_empty(&modules_aliases_map)) { | |
886 | + if (list_empty(&modules_aliases_map) || | |
887 | + load_module_by_device_modalias(modalias, is_booting()) == 2) { | |
880 | 888 | /* if module alias mapping is empty, |
881 | 889 | * queue it for loading later |
882 | 890 | */ |
@@ -893,8 +901,6 @@ static void handle_module_loading(const char *modalias) | ||
893 | 901 | } else { |
894 | 902 | ERROR("failed to allocate memory to store device id for deferred module loading.\n"); |
895 | 903 | } |
896 | - } else { | |
897 | - load_module_by_device_modalias(modalias); | |
898 | 904 | } |
899 | 905 | |
900 | 906 | } |
@@ -955,11 +961,6 @@ static int load_firmware(int fw_fd, int loading_fd, int data_fd) | ||
955 | 961 | return ret; |
956 | 962 | } |
957 | 963 | |
958 | -static int is_booting(void) | |
959 | -{ | |
960 | - return access("/dev/.booting", F_OK) == 0; | |
961 | -} | |
962 | - | |
963 | 964 | static void process_firmware_event(struct uevent *uevent) |
964 | 965 | { |
965 | 966 | char *root, *loading, *data; |
@@ -1077,6 +1078,7 @@ static void parse_line_module_alias(struct parse_state *state, int nargs, char * | ||
1077 | 1078 | static void parse_line_module_blacklist(struct parse_state *state, int nargs, char **args) |
1078 | 1079 | { |
1079 | 1080 | struct module_blacklist_node *node; |
1081 | + bool deferred; | |
1080 | 1082 | |
1081 | 1083 | if (!args || |
1082 | 1084 | (nargs != 2) || |
@@ -1085,8 +1087,13 @@ static void parse_line_module_blacklist(struct parse_state *state, int nargs, ch | ||
1085 | 1087 | return; |
1086 | 1088 | } |
1087 | 1089 | |
1088 | - /* this line does not being with "blacklist" */ | |
1089 | - if (strncmp(args[0], "blacklist", 9)) return; | |
1090 | + /* this line should be with "blacklist" or "deferred" */ | |
1091 | + if (!strncmp(args[0], "blacklist", 9)) | |
1092 | + deferred = false; | |
1093 | + else if (!strncmp(args[0], "deferred", 8)) | |
1094 | + deferred = true; | |
1095 | + else | |
1096 | + return; | |
1090 | 1097 | |
1091 | 1098 | node = (module_blacklist_node *) calloc(1, sizeof(*node)); |
1092 | 1099 | if (!node) return; |
@@ -1096,6 +1103,7 @@ static void parse_line_module_blacklist(struct parse_state *state, int nargs, ch | ||
1096 | 1103 | free(node); |
1097 | 1104 | return; |
1098 | 1105 | } |
1106 | + node->deferred = deferred; | |
1099 | 1107 | |
1100 | 1108 | list_add_tail(&modules_blacklist, &node->list); |
1101 | 1109 | } |
@@ -1293,6 +1301,7 @@ void device_init(bool child) | ||
1293 | 1301 | coldboot("/sys/class"); |
1294 | 1302 | coldboot("/sys/block"); |
1295 | 1303 | coldboot("/sys/devices"); |
1304 | + handle_deferred_module_loading(); | |
1296 | 1305 | close(open(COLDBOOT_DONE, O_WRONLY|O_CREAT|O_CLOEXEC, 0000)); |
1297 | 1306 | NOTICE("Coldboot took %.2fs.\n", t.duration()); |
1298 | 1307 | } |