diff options
-rw-r--r-- | util-linux/mdev.c | 154 |
1 files changed, 82 insertions, 72 deletions
diff --git a/util-linux/mdev.c b/util-linux/mdev.c index 63b55536a..8205a260a 100644 --- a/util-linux/mdev.c +++ b/util-linux/mdev.c | |||
@@ -1047,6 +1047,86 @@ static void signal_mdevs(unsigned my_pid) | |||
1047 | } | 1047 | } |
1048 | } | 1048 | } |
1049 | 1049 | ||
1050 | static void process_action(char *temp, unsigned my_pid) | ||
1051 | { | ||
1052 | char *fw; | ||
1053 | char *seq; | ||
1054 | char *action; | ||
1055 | char *env_devname; | ||
1056 | char *env_devpath; | ||
1057 | unsigned seqnum = seqnum; /* for compiler */ | ||
1058 | int seq_fd; | ||
1059 | smalluint op; | ||
1060 | |||
1061 | /* Hotplug: | ||
1062 | * env ACTION=... DEVPATH=... SUBSYSTEM=... [SEQNUM=...] mdev | ||
1063 | * ACTION can be "add", "remove", "change" | ||
1064 | * DEVPATH is like "/block/sda" or "/class/input/mice" | ||
1065 | */ | ||
1066 | env_devname = getenv("DEVNAME"); /* can be NULL */ | ||
1067 | G.subsystem = getenv("SUBSYSTEM"); | ||
1068 | action = getenv("ACTION"); | ||
1069 | env_devpath = getenv("DEVPATH"); | ||
1070 | if (!action || !env_devpath /*|| !G.subsystem*/) | ||
1071 | bb_show_usage(); | ||
1072 | fw = getenv("FIRMWARE"); | ||
1073 | seq = getenv("SEQNUM"); | ||
1074 | op = index_in_strings(keywords, action); | ||
1075 | |||
1076 | open_mdev_log(seq, my_pid); | ||
1077 | |||
1078 | seq_fd = -1; | ||
1079 | if (seq) { | ||
1080 | seqnum = atoll(seq); | ||
1081 | seq_fd = wait_for_seqfile(seqnum); | ||
1082 | } | ||
1083 | |||
1084 | dbg1("%s " | ||
1085 | "ACTION:%s SEQNUM:%s SUBSYSTEM:%s DEVNAME:%s DEVPATH:%s" | ||
1086 | "%s%s", | ||
1087 | curtime(), | ||
1088 | action, seq, G.subsystem, env_devname, env_devpath, | ||
1089 | fw ? " FW:" : "", fw ? fw : "" | ||
1090 | ); | ||
1091 | |||
1092 | snprintf(temp, PATH_MAX, "/sys%s", env_devpath); | ||
1093 | if (op == OP_remove) { | ||
1094 | /* Ignoring "remove firmware". It was reported | ||
1095 | * to happen and to cause erroneous deletion | ||
1096 | * of device nodes. */ | ||
1097 | if (!fw) | ||
1098 | make_device(env_devname, temp, op); | ||
1099 | } | ||
1100 | else { | ||
1101 | make_device(env_devname, temp, op); | ||
1102 | if (ENABLE_FEATURE_MDEV_LOAD_FIRMWARE) { | ||
1103 | if (op == OP_add && fw) | ||
1104 | load_firmware(fw, temp); | ||
1105 | } | ||
1106 | } | ||
1107 | |||
1108 | if (seq_fd >= 0) { | ||
1109 | xwrite_str(seq_fd, utoa(seqnum + 1)); | ||
1110 | signal_mdevs(my_pid); | ||
1111 | } | ||
1112 | } | ||
1113 | |||
1114 | static void initial_scan(char *temp) | ||
1115 | { | ||
1116 | struct stat st; | ||
1117 | |||
1118 | xstat("/", &st); | ||
1119 | G.root_major = major(st.st_dev); | ||
1120 | G.root_minor = minor(st.st_dev); | ||
1121 | |||
1122 | putenv((char*)"ACTION=add"); | ||
1123 | |||
1124 | /* Create all devices from /sys/dev hierarchy */ | ||
1125 | recursive_action("/sys/dev", | ||
1126 | ACTION_RECURSE | ACTION_FOLLOWLINKS, | ||
1127 | fileAction, dirAction, temp, 0); | ||
1128 | } | ||
1129 | |||
1050 | int mdev_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 1130 | int mdev_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
1051 | int mdev_main(int argc UNUSED_PARAM, char **argv) | 1131 | int mdev_main(int argc UNUSED_PARAM, char **argv) |
1052 | { | 1132 | { |
@@ -1071,86 +1151,16 @@ int mdev_main(int argc UNUSED_PARAM, char **argv) | |||
1071 | /* | 1151 | /* |
1072 | * Scan: mdev -s | 1152 | * Scan: mdev -s |
1073 | */ | 1153 | */ |
1074 | struct stat st; | ||
1075 | |||
1076 | #if ENABLE_FEATURE_MDEV_CONF | 1154 | #if ENABLE_FEATURE_MDEV_CONF |
1077 | /* Same as xrealloc_vector(NULL, 4, 0): */ | 1155 | /* Same as xrealloc_vector(NULL, 4, 0): */ |
1078 | G.rule_vec = xzalloc((1 << 4) * sizeof(*G.rule_vec)); | 1156 | G.rule_vec = xzalloc((1 << 4) * sizeof(*G.rule_vec)); |
1079 | #endif | 1157 | #endif |
1080 | xstat("/", &st); | ||
1081 | G.root_major = major(st.st_dev); | ||
1082 | G.root_minor = minor(st.st_dev); | ||
1083 | 1158 | ||
1084 | putenv((char*)"ACTION=add"); | 1159 | initial_scan(temp); |
1085 | |||
1086 | /* Create all devices from /sys/dev hierarchy */ | ||
1087 | recursive_action("/sys/dev", | ||
1088 | ACTION_RECURSE | ACTION_FOLLOWLINKS, | ||
1089 | fileAction, dirAction, temp, 0); | ||
1090 | } else { | 1160 | } else { |
1091 | char *fw; | 1161 | process_action(temp, getpid()); |
1092 | char *seq; | ||
1093 | char *action; | ||
1094 | char *env_devname; | ||
1095 | char *env_devpath; | ||
1096 | unsigned my_pid; | ||
1097 | unsigned seqnum = seqnum; /* for compiler */ | ||
1098 | int seq_fd; | ||
1099 | smalluint op; | ||
1100 | |||
1101 | /* Hotplug: | ||
1102 | * env ACTION=... DEVPATH=... SUBSYSTEM=... [SEQNUM=...] mdev | ||
1103 | * ACTION can be "add", "remove", "change" | ||
1104 | * DEVPATH is like "/block/sda" or "/class/input/mice" | ||
1105 | */ | ||
1106 | env_devname = getenv("DEVNAME"); /* can be NULL */ | ||
1107 | G.subsystem = getenv("SUBSYSTEM"); | ||
1108 | action = getenv("ACTION"); | ||
1109 | env_devpath = getenv("DEVPATH"); | ||
1110 | if (!action || !env_devpath /*|| !G.subsystem*/) | ||
1111 | bb_show_usage(); | ||
1112 | fw = getenv("FIRMWARE"); | ||
1113 | seq = getenv("SEQNUM"); | ||
1114 | op = index_in_strings(keywords, action); | ||
1115 | |||
1116 | my_pid = getpid(); | ||
1117 | open_mdev_log(seq, my_pid); | ||
1118 | |||
1119 | seq_fd = -1; | ||
1120 | if (seq) { | ||
1121 | seqnum = atoll(seq); | ||
1122 | seq_fd = wait_for_seqfile(seqnum); | ||
1123 | } | ||
1124 | |||
1125 | dbg1("%s " | ||
1126 | "ACTION:%s SUBSYSTEM:%s DEVNAME:%s DEVPATH:%s" | ||
1127 | "%s%s", | ||
1128 | curtime(), | ||
1129 | action, G.subsystem, env_devname, env_devpath, | ||
1130 | fw ? " FW:" : "", fw ? fw : "" | ||
1131 | ); | ||
1132 | |||
1133 | snprintf(temp, PATH_MAX, "/sys%s", env_devpath); | ||
1134 | if (op == OP_remove) { | ||
1135 | /* Ignoring "remove firmware". It was reported | ||
1136 | * to happen and to cause erroneous deletion | ||
1137 | * of device nodes. */ | ||
1138 | if (!fw) | ||
1139 | make_device(env_devname, temp, op); | ||
1140 | } | ||
1141 | else { | ||
1142 | make_device(env_devname, temp, op); | ||
1143 | if (ENABLE_FEATURE_MDEV_LOAD_FIRMWARE) { | ||
1144 | if (op == OP_add && fw) | ||
1145 | load_firmware(fw, temp); | ||
1146 | } | ||
1147 | } | ||
1148 | 1162 | ||
1149 | dbg1("%s exiting", curtime()); | 1163 | dbg1("%s exiting", curtime()); |
1150 | if (seq_fd >= 0) { | ||
1151 | xwrite_str(seq_fd, utoa(seqnum + 1)); | ||
1152 | signal_mdevs(my_pid); | ||
1153 | } | ||
1154 | } | 1164 | } |
1155 | 1165 | ||
1156 | if (ENABLE_FEATURE_CLEAN_UP) | 1166 | if (ENABLE_FEATURE_CLEAN_UP) |