|
@@ -398,15 +398,42 @@ out:
|
|
|
}
|
|
|
|
|
|
#ifdef CONFIG_ROOT_NFS
|
|
|
+
|
|
|
+#define NFSROOT_TIMEOUT_MIN 5
|
|
|
+#define NFSROOT_TIMEOUT_MAX 30
|
|
|
+#define NFSROOT_RETRY_MAX 5
|
|
|
+
|
|
|
static int __init mount_nfs_root(void)
|
|
|
{
|
|
|
char *root_dev, *root_data;
|
|
|
+ unsigned int timeout;
|
|
|
+ int try, err;
|
|
|
|
|
|
- if (nfs_root_data(&root_dev, &root_data) != 0)
|
|
|
- return 0;
|
|
|
- if (do_mount_root(root_dev, "nfs", root_mountflags, root_data) != 0)
|
|
|
+ err = nfs_root_data(&root_dev, &root_data);
|
|
|
+ if (err != 0)
|
|
|
return 0;
|
|
|
- return 1;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * The server or network may not be ready, so try several
|
|
|
+ * times. Stop after a few tries in case the client wants
|
|
|
+ * to fall back to other boot methods.
|
|
|
+ */
|
|
|
+ timeout = NFSROOT_TIMEOUT_MIN;
|
|
|
+ for (try = 1; ; try++) {
|
|
|
+ err = do_mount_root(root_dev, "nfs",
|
|
|
+ root_mountflags, root_data);
|
|
|
+ if (err == 0)
|
|
|
+ return 1;
|
|
|
+ if (try > NFSROOT_RETRY_MAX)
|
|
|
+ break;
|
|
|
+
|
|
|
+ /* Wait, in case the server refused us immediately */
|
|
|
+ ssleep(timeout);
|
|
|
+ timeout <<= 1;
|
|
|
+ if (timeout > NFSROOT_TIMEOUT_MAX)
|
|
|
+ timeout = NFSROOT_TIMEOUT_MAX;
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
}
|
|
|
#endif
|
|
|
|