Skip to content

Commit a4471ef

Browse files
build: retry MMCE IRX downloads on transient HTTP failures
1 parent c249bad commit a4471ef

2 files changed

Lines changed: 168 additions & 40 deletions

File tree

download_mmce.sh

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,28 @@ for file in "${FILES[@]}"; do
1414
import pathlib
1515
import shutil
1616
import sys
17+
import time
1718
import urllib.request
19+
import urllib.error
1820
1921
url = sys.argv[1]
2022
output = pathlib.Path(sys.argv[2])
2123
22-
with urllib.request.urlopen(url) as response, output.open("wb") as destination:
23-
shutil.copyfileobj(response, destination)
24+
last_error = None
25+
for attempt in range(5):
26+
try:
27+
with urllib.request.urlopen(url) as response, output.open("wb") as destination:
28+
shutil.copyfileobj(response, destination)
29+
last_error = None
30+
break
31+
except (urllib.error.HTTPError, urllib.error.URLError) as err:
32+
last_error = err
33+
if attempt == 4:
34+
raise
35+
time.sleep(2 ** attempt)
36+
37+
if last_error is not None:
38+
raise last_error
2439
PY
2540
mv "$REPO_FOLDER/$file.tmp" "$REPO_FOLDER/$file"
2641
fi

src/opl.c

Lines changed: 151 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -788,37 +788,109 @@ void setErrorMessage(int strId)
788788

789789
static int lscstatus = CONFIG_ALL;
790790
static int lscret = 0;
791+
static const char *configPathRedirectFile = "config.path";
792+
793+
static int readConfigPathRedirect(char *outPath, int outPathLen)
794+
{
795+
int fd;
796+
int len;
797+
798+
fd = open((char *)configPathRedirectFile, O_RDONLY);
799+
if (fd < 0)
800+
return 0;
801+
802+
len = read(fd, outPath, outPathLen - 1);
803+
close(fd);
804+
if (len <= 0)
805+
return 0;
806+
807+
while (len > 0 && (outPath[len - 1] == '\r' || outPath[len - 1] == '\n' || outPath[len - 1] == ' ' || outPath[len - 1] == '\t'))
808+
len--;
809+
outPath[len] = '\0';
810+
811+
return len > 0;
812+
}
813+
814+
static void writeConfigPathRedirect(const char *path)
815+
{
816+
int fd = open((char *)configPathRedirectFile, O_WRONLY | O_CREAT | O_TRUNC, 0666);
817+
if (fd >= 0) {
818+
write(fd, path, strlen(path));
819+
write(fd, "\n", 1);
820+
close(fd);
821+
}
822+
}
791823

792824
static int checkLoadConfigBDM(int types)
793825
{
794826
char path[64];
795827
int value;
796828
int bdm_result;
797-
int is_hdd = 0;
798829

799-
// check USB
830+
// Check BDM devices first (mass:/massX:/mmce:/mx4sio: etc).
800831
bdm_result = bdmFindPartition(path, "conf_opl.cfg", 0);
801-
// if not on USB, check BDM HDD
802-
if (bdm_result == 0) {
803-
// wait for up to 5 seconds for the HDD to spin up and become accessible...
804-
if (hddLoadModules() >= 0 && bdmHDDIsPresent(5000)) {
805-
bdm_result = bdmFindPartition(path, "conf_opl.cfg", 0);
806-
if (bdm_result)
807-
is_hdd = 1;
808-
}
809-
}
810832

811833
if (bdm_result) {
812834
configEnd();
813835
configInit(path);
814836
value = configReadMulti(types);
815837
config_set_t *configOPL = configGetByType(CONFIG_OPL);
816838
configSetInt(configOPL, CONFIG_OPL_BDM_MODE, START_MODE_AUTO);
817-
if (is_hdd != 0) {
839+
return value;
840+
}
841+
842+
return 0;
843+
}
844+
845+
static int checkLoadConfigMMCE(int types)
846+
{
847+
int value;
848+
DIR *dir = opendir("mmce0:");
849+
if (dir != NULL) {
850+
closedir(dir);
851+
configEnd();
852+
configInit("mmce0:");
853+
value = configReadMulti(types);
854+
if (value & CONFIG_OPL) {
855+
config_set_t *configOPL = configGetByType(CONFIG_OPL);
856+
configSetInt(configOPL, CONFIG_OPL_MMCE_MODE, START_MODE_AUTO);
857+
return value;
858+
}
859+
}
860+
861+
dir = opendir("mmce1:");
862+
if (dir != NULL) {
863+
closedir(dir);
864+
configEnd();
865+
configInit("mmce1:");
866+
value = configReadMulti(types);
867+
if (value & CONFIG_OPL) {
868+
config_set_t *configOPL = configGetByType(CONFIG_OPL);
869+
configSetInt(configOPL, CONFIG_OPL_MMCE_MODE, START_MODE_AUTO);
870+
return value;
871+
}
872+
}
873+
874+
return 0;
875+
}
876+
877+
static int checkLoadConfigBDMHDD(int types)
878+
{
879+
char path[64];
880+
int value;
881+
882+
// Bounded wait so BDM-on-HDD can be detected without long black-screen stalls.
883+
if (hddLoadModules() >= 0 && bdmHDDIsPresent(500)) {
884+
if (bdmFindPartition(path, "conf_opl.cfg", 0)) {
885+
configEnd();
886+
configInit(path);
887+
value = configReadMulti(types);
888+
config_set_t *configOPL = configGetByType(CONFIG_OPL);
889+
configSetInt(configOPL, CONFIG_OPL_BDM_MODE, START_MODE_AUTO);
818890
gEnableBdmHDD = 1;
819891
configSetInt(configOPL, CONFIG_OPL_ENABLE_BDMHDD, gEnableBdmHDD);
892+
return value;
820893
}
821-
return value;
822894
}
823895

824896
return 0;
@@ -851,11 +923,20 @@ static int checkLoadConfigHDD(int types)
851923
static int tryAlternateDevice(int types)
852924
{
853925
char pwd[8];
926+
char redirectPath[64];
854927
int value;
855928
DIR *dir;
856929

857930
getcwd(pwd, sizeof(pwd));
858931

932+
if (readConfigPathRedirect(redirectPath, sizeof(redirectPath))) {
933+
configEnd();
934+
configInit(redirectPath);
935+
value = configReadMulti(types);
936+
if (value & CONFIG_OPL)
937+
return value;
938+
}
939+
859940
// First, try the device that OPL booted from.
860941
if (!strncmp(pwd, "mass", 4) && (pwd[4] == ':' || pwd[5] == ':')) {
861942
if ((value = checkLoadConfigBDM(types)) != 0)
@@ -866,9 +947,15 @@ static int tryAlternateDevice(int types)
866947
}
867948

868949
// Config was not found on the boot device. Check all supported devices.
869-
// Check USB device
950+
// Check MMCE before BDM.
951+
if ((value = checkLoadConfigMMCE(types)) != 0)
952+
return value;
953+
// Check BDM devices.
870954
if ((value = checkLoadConfigBDM(types)) != 0)
871955
return value;
956+
// Check BDM HDD with a short bounded wait.
957+
if ((value = checkLoadConfigBDMHDD(types)) != 0)
958+
return value;
872959
// Check HDD
873960
if ((value = checkLoadConfigHDD(types)) != 0)
874961
return value;
@@ -906,6 +993,8 @@ static void _loadConfig()
906993
int value, themeID = -1, langID = -1;
907994
const char *temp;
908995
int result = configReadMulti(lscstatus);
996+
if ((lscstatus & CONFIG_OPL) && !(result & CONFIG_OPL))
997+
result = tryAlternateDevice(lscstatus);
909998

910999
if (lscstatus & CONFIG_OPL) {
9111000
if (result & CONFIG_OPL) {
@@ -1029,15 +1118,8 @@ static int trySaveConfigBDM(int types)
10291118
char path[64];
10301119
int bdm_result;
10311120

1032-
// check USB
1121+
// Check BDM devices first (mass:/massX:/mmce:/mx4sio: etc).
10331122
bdm_result = bdmFindPartition(path, "conf_opl.cfg", 1);
1034-
// if not on USB, check BDM HDD
1035-
if (bdm_result == 0) {
1036-
// wait for up to 5 seconds for the HDD to spin up and become accessible...
1037-
if (hddLoadModules() >= 0 && bdmHDDIsPresent(5000)) {
1038-
bdm_result = bdmFindPartition(path, "conf_opl.cfg", 1);
1039-
}
1040-
}
10411123

10421124
if (bdm_result) {
10431125
configSetMove(path);
@@ -1047,6 +1129,40 @@ static int trySaveConfigBDM(int types)
10471129
return -ENOENT;
10481130
}
10491131

1132+
static int trySaveConfigMMCE(int types)
1133+
{
1134+
DIR *dir = opendir("mmce0:");
1135+
if (dir != NULL) {
1136+
closedir(dir);
1137+
configSetMove("mmce0:");
1138+
return configWriteMulti(types);
1139+
}
1140+
1141+
dir = opendir("mmce1:");
1142+
if (dir != NULL) {
1143+
closedir(dir);
1144+
configSetMove("mmce1:");
1145+
return configWriteMulti(types);
1146+
}
1147+
1148+
return -ENOENT;
1149+
}
1150+
1151+
static int trySaveConfigBDMHDD(int types)
1152+
{
1153+
char path[64];
1154+
1155+
// Bounded wait so save can target BDM-on-HDD without long stalls.
1156+
if (hddLoadModules() >= 0 && bdmHDDIsPresent(500)) {
1157+
if (bdmFindPartition(path, "conf_opl.cfg", 1)) {
1158+
configSetMove(path);
1159+
return configWriteMulti(types);
1160+
}
1161+
}
1162+
1163+
return -ENOENT;
1164+
}
1165+
10501166
static int trySaveConfigHDD(int types)
10511167
{
10521168
hddLoadModules();
@@ -1067,30 +1183,19 @@ static int trySaveConfigMC(int types)
10671183

10681184
static int trySaveAlternateDevice(int types)
10691185
{
1070-
char pwd[8];
10711186
int value;
10721187

1073-
getcwd(pwd, sizeof(pwd));
1074-
1075-
// First, try the device that OPL booted from.
1076-
if (!strncmp(pwd, "mass", 4) && (pwd[4] == ':' || pwd[5] == ':')) {
1077-
if ((value = trySaveConfigBDM(types)) > 0)
1078-
return value;
1079-
} else if (!strncmp(pwd, "hdd", 3) && (pwd[3] == ':' || pwd[4] == ':')) {
1080-
if ((value = trySaveConfigHDD(types)) > 0)
1081-
return value;
1082-
}
1083-
1084-
// Config was not saved to the boot device. Try all supported devices.
1085-
// Try memory cards
1188+
// Save in deterministic order: MC -> MMCE -> BDM -> BDM-HDD -> HDD.
10861189
if (sysCheckMC() >= 0) {
10871190
if ((value = trySaveConfigMC(types)) > 0)
10881191
return value;
10891192
}
1090-
// Try a USB device
1193+
if ((value = trySaveConfigMMCE(types)) > 0)
1194+
return value;
10911195
if ((value = trySaveConfigBDM(types)) > 0)
10921196
return value;
1093-
// Try the HDD
1197+
if ((value = trySaveConfigBDMHDD(types)) > 0)
1198+
return value;
10941199
if ((value = trySaveConfigHDD(types)) > 0)
10951200
return value;
10961201

@@ -1193,6 +1298,8 @@ static void _saveConfig()
11931298
}
11941299

11951300
lscret = configWriteMulti(lscstatus);
1301+
if (lscret > 0)
1302+
writeConfigPathRedirect(configGetDir());
11961303
lscstatus = 0;
11971304
}
11981305

@@ -1667,6 +1774,12 @@ static void moduleCleanup(opl_io_module_t *mod, int exception, int modeSelected)
16671774

16681775
void deinit(int exception, int modeSelected)
16691776
{
1777+
/* Cut launch/exit latency by stopping queued art I/O before globally
1778+
* blocking the I/O worker. This avoids waiting for stale cover requests
1779+
* that are no longer needed once we are deinitializing. */
1780+
cacheAbortMmceImageLoadsTimed(0);
1781+
(void)cacheCancelPendingImageLoadsTimed(0);
1782+
16701783
// block all io ops, wait for the ones still running to finish
16711784
ioBlockOps(1);
16721785
guiExecDeferredOps();

0 commit comments

Comments
 (0)