X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=init%2Fdo_mounts.c;h=2974c8b3b351b4a15b38acca4478e4032fece9fa;hb=5d48421be3c8a9f753d61b826ecb3ad287d867c0;hp=b2eee02e0f83fd720f38cf83a2b5e58ea27997b1;hpb=ac69e0928054ff29a5049902fb477f9c7605c773;p=android-x86%2Fkernel.git diff --git a/init/do_mounts.c b/init/do_mounts.c index b2eee02e0f83..2974c8b3b351 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -400,15 +400,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