cdrom.c: workaround race conditions during media detection (ALT#30315)

This commit is contained in:
Дмитрий Левин 2014-12-17 16:48:24 +00:00 committed by Michael Shigorin
parent a1a557fa6f
commit 542567af7b

63
cdrom.c
View File

@ -141,12 +141,25 @@ static enum return_type try_with_device(char * dev_name, char * dev_model)
return do_with_device(dev_name, dev_model); return do_with_device(dev_name, dev_model);
} }
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
int try_automatic(char ** medias, char ** medias_models) int try_automatic(char ** medias, char ** medias_models)
{ {
static char * already_tried[50] = { NULL }; static char * already_tried[50] = { NULL };
char ** model = medias_models; char ** model = medias_models;
char ** ptr = medias; char ** ptr = medias;
int i = 0; int i = 0;
if (!medias) {
for (; i < ARRAY_SIZE(already_tried); ++i) {
if (!already_tried[i])
break;
free(already_tried[i]);
already_tried[i] = NULL;
}
return -1;
}
while (ptr && *ptr) { while (ptr && *ptr) {
char ** p; char ** p;
for (p = already_tried; p && *p; p++) for (p = already_tried; p && *p; p++)
@ -195,23 +208,51 @@ enum return_type cdrom_prepare(void)
get_medias(CDROM, &medias, &medias_models); get_medias(CDROM, &medias, &medias_models);
if (IS_AUTOMATIC) { if (IS_AUTOMATIC) {
unsigned int j;
for (j = 0; j < 5; ++j) {
if (j) {
wait_message("Waiting %d second%s for CD/DVD/Pendrive media to appear",
j, j > 1 ? "s" : "");
sleep(1);
/* drop medias */
for (ptr = medias; *ptr; ++ptr)
free(*ptr);
free(medias);
/* drop medias_models */
for (ptr = medias_models; *ptr; ++ptr)
free(*ptr);
free(medias_models);
/* drop already_tried */
try_automatic(NULL, NULL);
/* refill medias and medias_models;
note that get_medias() leaks memory */
get_medias(CDROM, &medias, &medias_models);
}
if ((i = try_automatic(medias, medias_models)) != -1) {
if (j) {
log_message("found /dev/%s %s after %d seconds of waiting",
medias[i], medias_models[i], j);
remove_wait_message();
}
return do_with_device(medias[i], medias_models[i]);
}
}
if (j)
remove_wait_message();
ptr = medias; ptr = medias;
while (ptr && *ptr) { while (ptr && *ptr) {
count++; count++;
ptr++; ptr++;
} }
if ((i = try_automatic(medias, medias_models)) != -1)
return do_with_device(medias[i], medias_models[i]);
if (count == 0) { if (count == 0) {
/* too bad, let's recount one more time */ stg1_error_message("No CD/DVD/Pendrive found.");
ptr = medias;
while (ptr && *ptr) {
count++;
ptr++;
}
if (count == 0)
stg1_error_message("No CD/DVD/Pendrive found.");
i = ask_insmod(); i = ask_insmod();
if (i == RETURN_BACK) if (i == RETURN_BACK)