system/corennnnn
リビジョン | 31627ba2253cb324d4223e3b1cbe5a7e6acb881a (tree) |
---|---|
日時 | 2016-11-09 00:56:26 |
作者 | Chih-Wei Huang <cwhuang@linu...> |
コミッター | 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 |
@@ -774,7 +775,7 @@ static void handle_generic_device_event(struct uevent *uevent) | ||
774 | 775 | uevent->major, uevent->minor, links); |
775 | 776 | } |
776 | 777 | |
777 | -static int is_module_blacklisted(const char *name) | |
778 | +static int is_module_blacklisted_or_deferred(const char *name, bool need_deferred) | |
778 | 779 | { |
779 | 780 | struct listnode *blklst_node; |
780 | 781 | struct module_blacklist_node *blacklist; |
@@ -789,7 +790,7 @@ static int is_module_blacklisted(const char *name) | ||
789 | 790 | list); |
790 | 791 | if (!strcmp(name, blacklist->name)) { |
791 | 792 | INFO("modules %s is blacklisted\n", name); |
792 | - ret = 1; | |
793 | + ret = blacklist->deferred ? (need_deferred ? 2 : 0) : 1; | |
793 | 794 | goto out; |
794 | 795 | } |
795 | 796 | } |
@@ -798,7 +799,7 @@ out: | ||
798 | 799 | return ret; |
799 | 800 | } |
800 | 801 | |
801 | -static int load_module_by_device_modalias(const char *id) | |
802 | +static int load_module_by_device_modalias(const char *id, bool need_deferred) | |
802 | 803 | { |
803 | 804 | struct listnode *alias_node; |
804 | 805 | struct module_alias_node *alias; |
@@ -811,8 +812,9 @@ static int load_module_by_device_modalias(const char *id) | ||
811 | 812 | if (fnmatch(alias->pattern, id, 0) == 0) { |
812 | 813 | INFO("trying to load module %s due to uevents\n", alias->name); |
813 | 814 | |
814 | - if (!is_module_blacklisted(alias->name)) { | |
815 | - if (insmod_by_dep(alias->name, "", NULL, 0, NULL)) { | |
815 | + ret = is_module_blacklisted_or_deferred(alias->name, need_deferred); | |
816 | + if (ret == 0) { | |
817 | + if ((ret = insmod_by_dep(alias->name, "", NULL, 0, NULL))) { | |
816 | 818 | /* cannot load module. try another one since |
817 | 819 | * there may be another match. |
818 | 820 | */ |
@@ -821,8 +823,9 @@ static int load_module_by_device_modalias(const char *id) | ||
821 | 823 | } else { |
822 | 824 | /* loading was successful */ |
823 | 825 | INFO("loaded module %s due to uevents\n", alias->name); |
824 | - ret = 0; | |
825 | 826 | } |
827 | + } else { | |
828 | + NOTICE("blacklisted module %s: %d\n", alias->name, ret); | |
826 | 829 | } |
827 | 830 | } |
828 | 831 | } |
@@ -846,7 +849,7 @@ static void handle_deferred_module_loading() | ||
846 | 849 | |
847 | 850 | if (alias && alias->pattern) { |
848 | 851 | INFO("deferred loading of module for %s\n", alias->pattern); |
849 | - load_module_by_device_modalias(alias->pattern); | |
852 | + load_module_by_device_modalias(alias->pattern, false); | |
850 | 853 | free(alias->pattern); |
851 | 854 | list_remove(node); |
852 | 855 | free(alias); |
@@ -863,7 +866,7 @@ static int module_probe(int argc, char **argv) | ||
863 | 866 | } |
864 | 867 | |
865 | 868 | // is it a modalias? |
866 | - int ret = load_module_by_device_modalias(argv[1]); | |
869 | + int ret = load_module_by_device_modalias(argv[1], false); | |
867 | 870 | if (ret) { |
868 | 871 | // treat it as a module name |
869 | 872 | std::string options; |
@@ -905,6 +908,11 @@ int modprobe_main(int argc, char **argv) | ||
905 | 908 | return module_probe(argc, argv); |
906 | 909 | } |
907 | 910 | |
911 | +static int is_booting(void) | |
912 | +{ | |
913 | + return access("/dev/.booting", F_OK) == 0; | |
914 | +} | |
915 | + | |
908 | 916 | static void handle_module_loading(const char *modalias) |
909 | 917 | { |
910 | 918 | struct module_alias_node *node; |
@@ -915,13 +923,13 @@ static void handle_module_loading(const char *modalias) | ||
915 | 923 | if (list_empty(&modules_aliases_map)) { |
916 | 924 | if (read_modules_aliases() == 0) { |
917 | 925 | read_modules_blacklist(); |
918 | - handle_deferred_module_loading(); | |
919 | 926 | } |
920 | 927 | } |
921 | 928 | |
922 | 929 | if (!modalias) return; |
923 | 930 | |
924 | - if (list_empty(&modules_aliases_map)) { | |
931 | + if (list_empty(&modules_aliases_map) || | |
932 | + load_module_by_device_modalias(modalias, is_booting()) == 2) { | |
925 | 933 | /* if module alias mapping is empty, |
926 | 934 | * queue it for loading later |
927 | 935 | */ |
@@ -938,10 +946,7 @@ static void handle_module_loading(const char *modalias) | ||
938 | 946 | } else { |
939 | 947 | ERROR("failed to allocate memory to store device id for deferred module loading.\n"); |
940 | 948 | } |
941 | - } else { | |
942 | - load_module_by_device_modalias(modalias); | |
943 | 949 | } |
944 | - | |
945 | 950 | } |
946 | 951 | |
947 | 952 | static void handle_device_event(struct uevent *uevent) |
@@ -1000,11 +1005,6 @@ static int load_firmware(int fw_fd, int loading_fd, int data_fd) | ||
1000 | 1005 | return ret; |
1001 | 1006 | } |
1002 | 1007 | |
1003 | -static int is_booting(void) | |
1004 | -{ | |
1005 | - return access("/dev/.booting", F_OK) == 0; | |
1006 | -} | |
1007 | - | |
1008 | 1008 | static void process_firmware_event(struct uevent *uevent) |
1009 | 1009 | { |
1010 | 1010 | char *root, *loading, *data; |
@@ -1122,6 +1122,7 @@ static void parse_line_module_alias(struct parse_state *state, int nargs, char * | ||
1122 | 1122 | static void parse_line_module_blacklist(struct parse_state *state, int nargs, char **args) |
1123 | 1123 | { |
1124 | 1124 | struct module_blacklist_node *node; |
1125 | + bool deferred; | |
1125 | 1126 | |
1126 | 1127 | if (!args || |
1127 | 1128 | (nargs != 2) || |
@@ -1130,8 +1131,13 @@ static void parse_line_module_blacklist(struct parse_state *state, int nargs, ch | ||
1130 | 1131 | return; |
1131 | 1132 | } |
1132 | 1133 | |
1133 | - /* this line does not being with "blacklist" */ | |
1134 | - if (strncmp(args[0], "blacklist", 9)) return; | |
1134 | + /* this line does not being with "blacklist" or "deferred" */ | |
1135 | + if (!strncmp(args[0], "blacklist", 9)) | |
1136 | + deferred = false; | |
1137 | + else if (!strncmp(args[0], "deferred", 8)) | |
1138 | + deferred = true; | |
1139 | + else | |
1140 | + return; | |
1135 | 1141 | |
1136 | 1142 | node = (module_blacklist_node *) calloc(1, sizeof(*node)); |
1137 | 1143 | if (!node) return; |
@@ -1141,6 +1147,7 @@ static void parse_line_module_blacklist(struct parse_state *state, int nargs, ch | ||
1141 | 1147 | free(node); |
1142 | 1148 | return; |
1143 | 1149 | } |
1150 | + node->deferred = deferred; | |
1144 | 1151 | |
1145 | 1152 | list_add_tail(&modules_blacklist, &node->list); |
1146 | 1153 | } |
@@ -1335,6 +1342,7 @@ void device_init(bool child) | ||
1335 | 1342 | coldboot("/sys/class"); |
1336 | 1343 | coldboot("/sys/block"); |
1337 | 1344 | coldboot("/sys/devices"); |
1345 | + handle_deferred_module_loading(); | |
1338 | 1346 | close(open(COLDBOOT_DONE, O_WRONLY|O_CREAT|O_CLOEXEC, 0000)); |
1339 | 1347 | NOTICE("Coldboot took %.2fs.\n", t.duration()); |
1340 | 1348 | } |