Chris Lumens wrote:
Jeremy Katz wrote:
Could even do 5-10 tries over 30 seconds and if we don't succeed in that
long, then fail. That would save people from having to pass an obscure
parameter and make things just work for them
We could even treat this like TCP and do the exponential backoff. I'd
be fine with a patch that does that. Could we also get one in Fedora,
if appropriate there too?
Unfortunately, getKickstartFile() doesn't return a status (it's void),
it just branches out into various functions depending on the ks= value:
kickstartFrom{Nfs|Url|Floppy|HD|BD|CD}()
So, the try-again logic needs to be repeated a few times as shown in the
attached proof-of-concept patch (not tested yet!).
- not needed for NFS or Url since those aren't local USB devices.
- Floppy and CD need to re-try probeDevices() a few times
- HD and BD need to re-try mounting the device in
getFileFromBlockDevice()
The Floppy code already sleeps for USB devices, so I copied-and-pasted
it for CDs (but increased the sleep to 2 seconds).
For HD & BD, I did something slightly differently and did an exponential
backoff as Chris suggested.
If you like this approach, let me know and I'll test it.
Jeff
diff --git a/loader2/cdinstall.c b/loader2/cdinstall.c
index 90afdfb..0f68de8 100644
--- a/loader2/cdinstall.c
+++ b/loader2/cdinstall.c
@@ -427,13 +427,21 @@ void setKickstartCD(struct loaderData_s * loaderData, int argc, char ** argv) {
}
int kickstartFromCD(char *kssrc) {
- int rc, i;
+ int i = 0, rc;
char *p, *kspath;
struct device ** devices;
logMessage(INFO, "getting kickstart file from first CDROM");
devices = probeDevices(CLASS_CDROM, BUS_UNSPEC, 0);
+ /* usb can take some time to settle, even with the various hacks we
+ * have in place. some systems use portable USB CD-ROM drives, try to
+ * make sure there really isn't one before bailing */
+ while (!devices && (i++ < 10)) {
+ sleep(2);
+ logMessage(DEBUGLVL, "sleeping to wait for a USB CD-ROM");
+ devices = probeDevices(CLASS_CDROM, BUS_UNSPEC, 0);
+ }
if (!devices) {
logMessage(ERROR, "No CDROM devices found!");
return 1;
diff --git a/loader2/method.c b/loader2/method.c
index 1905f9f..0b694f4 100644
--- a/loader2/method.c
+++ b/loader2/method.c
@@ -644,8 +644,11 @@ int copyFileAndLoopbackMount(int fd, char * dest,
2 - could not mount device as ext2, vfat, or iso9660
3 - file named path not there
*/
+#define TRYMOUNT(fs) \
+ (doPwMount("/tmp/srcdev", "/tmp/mnt", (fs), IMOUNT_RDONLY, NULL))
+
int getFileFromBlockDevice(char *device, char *path, char * dest) {
- int rc;
+ int i = 0, s = 1, rc;
char file[4096];
logMessage(INFO, "getFileFromBlockDevice(%s, %s)", device, path);
@@ -655,9 +658,16 @@ int getFileFromBlockDevice(char *device, char *path, char * dest) {
return 1;
}
- if (doPwMount("/tmp/srcdev", "/tmp/mnt", "vfat", IMOUNT_RDONLY, NULL) &&
- doPwMount("/tmp/srcdev", "/tmp/mnt", "ext2", IMOUNT_RDONLY, NULL) &&
- doPwMount("/tmp/srcdev", "/tmp/mnt", "iso9660", IMOUNT_RDONLY, NULL)) {
+ /* some USB thumb drives and hard drives are slow to initialize */
+ /* retry up to 5 times or 31 seconds */
+ rc = TRYMOUNT("vfat") && TRYMOUNT("ext2") && TRYMOUNT("iso9660");
+ while (rc && (i++ < 5)) {
+ sleep(s);
+ s <<= 1;
+ logMessage(DEBUGLVL, "sleeping to wait for USB storage devices");
+ rc = TRYMOUNT("vfat") && TRYMOUNT("ext2") && TRYMOUNT("iso9660");
+ }
+ if (rc) {
logMessage(ERROR, "failed to mount /dev/%s: %s", device,
strerror(errno));
return 2;
_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/anaconda-devel-list