Re: [master] Sleep if the kickstart file read fails (#537361)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

On 11/13/2009 11:30 AM, Ales Kozumplik wrote:
If a read from a block device (like USB key) or a cdrom (USB cdrom) fails, sleep
a bit to give the device some time to initialize. Return status of the mount
command is checked so waiting occurs only if there is a reasonable chance that
the device might eventually come online. This required extending our existing
mounting methods to report the correct mount error code.
---
  isys/imount.c      |   40 ++++++++++++++++++++++++++++++++++++++--
  isys/imount.h      |   14 +++++++++++---
  loader/cdinstall.c |    8 ++++++++
  loader/kickstart.c |    8 ++++++++
  loader/method.c    |   12 ++++++++++--
  5 files changed, 75 insertions(+), 7 deletions(-)

diff --git a/isys/imount.c b/isys/imount.c
index a62e223..46686c2 100644
--- a/isys/imount.c
+++ b/isys/imount.c
@@ -189,8 +189,29 @@ int mountCommandWrapper(int mode, char *dev, char *where, char *fs,
          free(device);
      }

-    if (!WIFEXITED(status) || (WIFEXITED(status)&&  WEXITSTATUS(status)))
-       return IMOUNT_ERR_OTHER;
+    if (!WIFEXITED(status))
+        return IMOUNT_ERR_OTHER;
+    else if ( (rc = WEXITSTATUS(status)) ) {
+        /* Refer to 'man mount' for the meaning of the error codes. */
+        switch (rc) {
+        case 1:
+            return IMOUNT_ERR_PERMISSIONS;
+        case 2:
+            return IMOUNT_ERR_SYSTEM;
+        case 4:
+            return IMOUNT_ERR_MOUNTINTERNAL;
+        case 8:
+            return IMOUNT_ERR_USERINTERRUPT;
+        case 16:
+            return IMOUNT_ERR_MTAB;
+        case 32:
+            return IMOUNT_ERR_MOUNTFAILURE;
+        case 64:
+            return IMOUNT_ERR_PARTIALSUCC;
+        default:
+            return IMOUNT_ERR_OTHER;
+        }
+    }

      return 0;
  }
@@ -230,6 +251,21 @@ int mkdirChain(char * origChain) {
      return 0;
  }

+/* Returns true iff it is possible that the mount command that have returned
+ * 'errno' might succeed at a later time (think e.g. not yet initialized USB
+ * device, etc.) */
+int mountMightSucceedLater(int mountRc)

parameter name mountRc

+{
+    int rc;
+    switch (errno) {

Switch on errno, this does not seem right.

+    case IMOUNT_ERR_MOUNTFAILURE:
+        rc = 1;
+    default:
+        rc = 0;
+    }
+    return rc;
+}
+
  static int mkdirIfNone(char * directory) {
      int rc, mkerr;
      char * chptr;
diff --git a/isys/imount.h b/isys/imount.h
index 95cca38..9fa6769 100644
--- a/isys/imount.h
+++ b/isys/imount.h
@@ -20,9 +20,16 @@
  #ifndef H_IMOUNT
  #define H_IMOUNT

-#define IMOUNT_ERR_ERRNO	1
-#define IMOUNT_ERR_OTHER	2
-#define IMOUNT_ERR_MODE		3
+#define IMOUNT_ERR_ERRNO          1
+#define IMOUNT_ERR_OTHER          2
+#define IMOUNT_ERR_MODE           3
+#define IMOUNT_ERR_PERMISSIONS    4
+#define IMOUNT_ERR_SYSTEM         5
+#define IMOUNT_ERR_MOUNTINTERNAL  6
+#define IMOUNT_ERR_USERINTERRUPT  7
+#define IMOUNT_ERR_MTAB           8
+#define IMOUNT_ERR_MOUNTFAILURE   9
+#define IMOUNT_ERR_PARTIALSUCC    10

  #include<sys/mount.h>		/* for umount() */

@@ -36,5 +43,6 @@
  int doPwMount(char *dev, char *where, char *fs, char *options, char **err);
  int doPwUmount(char *where, char **err);
  int mkdirChain(char * origChain);
+int mountMightSucceedLater(int mountRc);

  #endif
diff --git a/loader/cdinstall.c b/loader/cdinstall.c
index d74396e..cc39691 100644
--- a/loader/cdinstall.c
+++ b/loader/cdinstall.c
@@ -490,6 +490,14 @@ int kickstartFromCD(char *kssrc) {
      logMessage(INFO, "getting kickstart file from first CDROM");

      devices = getDevices(DEVICE_CDROM);
+    /* 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 */
+    for (i = 0; !devices&&  i<  10; ++i) {
+        logMessage(INFO, "sleeping to wait for a USB CD-ROM");
+        sleep(2);
+        devices = getDevices(DEVICE_CDROM);
+    }
      if (!devices) {
          logMessage(ERROR, "No CDROM devices found!");
          return 1;
diff --git a/loader/kickstart.c b/loader/kickstart.c
index b92c6da..cbd26b3 100644
--- a/loader/kickstart.c
+++ b/loader/kickstart.c
@@ -252,6 +252,14 @@ int kickstartFromRemovable(char *kssrc) {

      logMessage(INFO, "doing kickstart from removable media");
      devices = getDevices(DEVICE_DISK);
+    /* 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. */
+    for (i = 0; !devices&&  i<  10; ++i) {
+        logMessage(INFO, "sleeping to wait for a USB disk");
+        sleep(2);
+        devices = getDevices(DEVICE_DISK);
+    }
      if (!devices) {
          logMessage(ERROR, "no disks");
          return 1;
diff --git a/loader/method.c b/loader/method.c
index ebfe557..12a2fa8 100644
--- a/loader/method.c
+++ b/loader/method.c
@@ -466,12 +466,20 @@ int copyFileAndLoopbackMount(int fd, char * dest, char * device, char * mntpoint
        3 - file named path not there
  */
  int getFileFromBlockDevice(char *device, char *path, char * dest) {
-    int rc;
+    int rc, i;
      char file[4096];

      logMessage(INFO, "getFileFromBlockDevice(%s, %s)", device, path);

-    if (doPwMount(device, "/tmp/mnt", "auto", "ro", NULL)) {
+    /* some USB thumb drives and hard drives are slow to initialize */
+    /* retry up to 5 times or 31 seconds */
+    rc = doPwMount(device, "/tmp/mnt", "auto", "ro", NULL);
+    for (i = 0; mountMightSucceedLater(rc)&&  i<  5; ++i) {
+        logMessage(INFO, "sleeping to wait for USB storage devices");
+        sleep(1<<  i);
+        rc = doPwMount(device, "/tmp/mnt", "auto", "ro", NULL);
+    }
+    if (rc) {
          logMessage(ERROR, "failed to mount /dev/%s: %m", device);
          return 2;
      }

Other then that it looks good,

Regards,

Hans

_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/anaconda-devel-list

[Index of Archives]     [Kickstart]     [Fedora Users]     [Fedora Legacy List]     [Fedora Maintainers]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [Yosemite Photos]     [KDE Users]     [Fedora Tools]
  Powered by Linux