summaryrefslogtreecommitdiff
path: root/init/do_mounts.c
diff options
context:
space:
mode:
authorClark Williams <williams@redhat.com>2012-01-25 21:31:16 -0600
committerClark Williams <williams@redhat.com>2012-01-25 21:31:16 -0600
commit974f4b86951972b133b4ec5b36956b979dea08d0 (patch)
tree090b441b1c96f708e8a033c7f88fa383dd1e7cba /init/do_mounts.c
parent40a54e2e116950a27dbd0a46a7b1ff8e982de477 (diff)
parent3499d6424f682a58761d827012567c552b053842 (diff)
Merge commit 'v3.2.2' into rt-3.2.2-rt10
Diffstat (limited to 'init/do_mounts.c')
-rw-r--r--init/do_mounts.c35
1 files changed, 31 insertions, 4 deletions
diff --git a/init/do_mounts.c b/init/do_mounts.c
index 0f6e1d985a3b..db6e5ee0e1db 100644
--- a/init/do_mounts.c
+++ b/init/do_mounts.c
@@ -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