You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
82 lines
2.6 KiB
82 lines
2.6 KiB
diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c |
|
index bdd7c24..89b90a1 100644 |
|
--- a/utils/mount/stropts.c |
|
+++ b/utils/mount/stropts.c |
|
@@ -931,19 +931,45 @@ static int nfs_try_mount(struct nfsmount_info *mi) |
|
* failed so far, but fail immediately if there is a local |
|
* error (like a bad mount option). |
|
* |
|
- * ESTALE is also a temporary error because some servers |
|
- * return ESTALE when a share is temporarily offline. |
|
+ * If there is a remote error, like ESTALE or RPC_PROGNOTREGISTERED |
|
+ * then it is probably permanent, but there is a small chance |
|
+ * the it is temporary can we caught the server at an awkward |
|
+ * time during start-up. So require that we see three of those |
|
+ * before treating them as permanent. |
|
+ * For ECONNREFUSED, wait a bit longer as there is often a longer |
|
+ * gap between the network being ready and the NFS server starting. |
|
* |
|
* Returns 1 if we should fail immediately, or 0 if we |
|
* should retry. |
|
*/ |
|
static int nfs_is_permanent_error(int error) |
|
{ |
|
+ static int prev_error; |
|
+ static int rpt_cnt; |
|
+ |
|
+ if (error == prev_error) |
|
+ rpt_cnt += 1; |
|
+ else |
|
+ rpt_cnt = 1; |
|
+ prev_error = error; |
|
+ |
|
switch (error) { |
|
case ESTALE: |
|
- case ETIMEDOUT: |
|
+ case EOPNOTSUPP: /* aka RPC_PROGNOTREGISTERED */ |
|
+ /* If two in a row, assume permanent */ |
|
+ return rpt_cnt >= 3; |
|
case ECONNREFUSED: |
|
+ /* Like the above, this can be temporary during a |
|
+ * small window. However it is typically a larger |
|
+ * window than for the others, and we have historically |
|
+ * treated this as a temporary (i.e. long timeout) |
|
+ * error with no complaints, so continue to treat |
|
+ * it as temporary. |
|
+ */ |
|
+ return 0; /* temporary */ |
|
+ case ETIMEDOUT: |
|
case EHOSTUNREACH: |
|
+ case EAGAIN: |
|
return 0; /* temporary */ |
|
default: |
|
return 1; /* permanent */ |
|
@@ -987,7 +1013,7 @@ static int nfsmount_fg(struct nfsmount_info *mi) |
|
if (secs > 10) |
|
secs = 10; |
|
} |
|
- }; |
|
+ } |
|
|
|
mount_error(mi->spec, mi->node, errno); |
|
return EX_FAIL; |
|
@@ -1005,8 +1031,7 @@ static int nfsmount_parent(struct nfsmount_info *mi) |
|
if (nfs_try_mount(mi)) |
|
return EX_SUCCESS; |
|
|
|
- /* retry background mounts when the server is not up */ |
|
- if (nfs_is_permanent_error(errno) && errno != EOPNOTSUPP) { |
|
+ if (nfs_is_permanent_error(errno)) { |
|
mount_error(mi->spec, mi->node, errno); |
|
return EX_FAIL; |
|
} |
|
@@ -1041,8 +1066,7 @@ static int nfsmount_child(struct nfsmount_info *mi) |
|
if (nfs_try_mount(mi)) |
|
return EX_SUCCESS; |
|
|
|
- /* retry background mounts when the server is not up */ |
|
- if (nfs_is_permanent_error(errno) && errno != EOPNOTSUPP) |
|
+ if (nfs_is_permanent_error(errno)) |
|
break; |
|
|
|
if (time(NULL) > timeout)
|
|
|