cdrom.c: workaround race conditions during media detection (ALT#30315)
This commit is contained in:
parent
a1a557fa6f
commit
542567af7b
63
cdrom.c
63
cdrom.c
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user