summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2009-01-27 17:47:06 -0500
committerSteve Dickson <steved@redhat.com>2009-01-27 17:47:06 -0500
commit3163dabcf0a6b992859508368baf67c918d2c091 (patch)
tree8a09fe6d74a9b5dbaa26cf949ffdd63e67624745
parent9d5ee403d5d4fd27ea41a674ca2e99ca1daa9f25 (diff)
downloadnfs-utils-3163dabcf0a6b992859508368baf67c918d2c091.tar.gz
nfs-utils-3163dabcf0a6b992859508368baf67c918d2c091.tar.xz
nfs-utils-3163dabcf0a6b992859508368baf67c918d2c091.zip
text-based mount command: fix mount option rewriting logic
Fix a bunch of corner cases in the text-based mount option rewriting logic. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Steve Dickson <steved@redhat.com>
-rw-r--r--utils/mount/stropts.c113
1 files changed, 79 insertions, 34 deletions
diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c
index 99be0f3..319be71 100644
--- a/utils/mount/stropts.c
+++ b/utils/mount/stropts.c
@@ -309,6 +309,81 @@ static int nfs_is_permanent_error(int error)
}
}
+static int nfs_construct_new_options(struct mount_options *options,
+ struct pmap *nfs_pmap,
+ struct pmap *mnt_pmap)
+{
+ char new_option[64];
+
+ po_remove_all(options, "nfsprog");
+ po_remove_all(options, "mountprog");
+
+ po_remove_all(options, "v2");
+ po_remove_all(options, "v3");
+ po_remove_all(options, "vers");
+ po_remove_all(options, "nfsvers");
+ snprintf(new_option, sizeof(new_option) - 1,
+ "vers=%lu", nfs_pmap->pm_vers);
+ if (po_append(options, new_option) == PO_FAILED)
+ return 0;
+
+ po_remove_all(options, "proto");
+ po_remove_all(options, "udp");
+ po_remove_all(options, "tcp");
+ switch (nfs_pmap->pm_prot) {
+ case IPPROTO_TCP:
+ snprintf(new_option, sizeof(new_option) - 1,
+ "proto=tcp");
+ if (po_append(options, new_option) == PO_FAILED)
+ return 0;
+ break;
+ case IPPROTO_UDP:
+ snprintf(new_option, sizeof(new_option) - 1,
+ "proto=udp");
+ if (po_append(options, new_option) == PO_FAILED)
+ return 0;
+ break;
+ }
+
+ po_remove_all(options, "port");
+ if (nfs_pmap->pm_port != NFS_PORT) {
+ snprintf(new_option, sizeof(new_option) - 1,
+ "port=%lu", nfs_pmap->pm_port);
+ if (po_append(options, new_option) == PO_FAILED)
+ return 0;
+ }
+
+ po_remove_all(options, "mountvers");
+ snprintf(new_option, sizeof(new_option) - 1,
+ "mountvers=%lu", mnt_pmap->pm_vers);
+ if (po_append(options, new_option) == PO_FAILED)
+ return 0;
+
+ po_remove_all(options, "mountproto");
+ switch (mnt_pmap->pm_prot) {
+ case IPPROTO_TCP:
+ snprintf(new_option, sizeof(new_option) - 1,
+ "mountproto=tcp");
+ if (po_append(options, new_option) == PO_FAILED)
+ return 0;
+ break;
+ case IPPROTO_UDP:
+ snprintf(new_option, sizeof(new_option) - 1,
+ "mountproto=udp");
+ if (po_append(options, new_option) == PO_FAILED)
+ return 0;
+ break;
+ }
+
+ po_remove_all(options, "mountport");
+ snprintf(new_option, sizeof(new_option) - 1,
+ "mountport=%lu", mnt_pmap->pm_port);
+ if (po_append(options, new_option) == PO_FAILED)
+ return 0;
+
+ return 1;
+}
+
/*
* Reconstruct the mount option string based on a portmapper probe
* of the server. Returns one if the server's portmapper returned
@@ -325,7 +400,7 @@ static int nfs_is_permanent_error(int error)
static struct mount_options *nfs_rewrite_mount_options(char *str)
{
struct mount_options *options;
- char *option, new_option[64];
+ char *option;
clnt_addr_t mnt_server = { };
clnt_addr_t nfs_server = { };
@@ -366,42 +441,12 @@ static struct mount_options *nfs_rewrite_mount_options(char *str)
goto err;
}
- snprintf(new_option, sizeof(new_option) - 1,
- "nfsvers=%lu", nfs_server.pmap.pm_vers);
- if (po_append(options, new_option) == PO_FAILED)
+ if (!nfs_construct_new_options(options,
+ &nfs_server.pmap, &mnt_server.pmap)) {
+ errno = EINVAL;
goto err;
-
- if (nfs_server.pmap.pm_prot == IPPROTO_TCP)
- snprintf(new_option, sizeof(new_option) - 1,
- "proto=tcp");
- else
- snprintf(new_option, sizeof(new_option) - 1,
- "proto=udp");
- if (po_append(options, new_option) == PO_FAILED)
- goto err;
-
- if (nfs_server.pmap.pm_port != NFS_PORT) {
- snprintf(new_option, sizeof(new_option) - 1,
- "port=%lu", nfs_server.pmap.pm_port);
- if (po_append(options, new_option) == PO_FAILED)
- goto err;
-
}
- if (mnt_server.pmap.pm_prot == IPPROTO_TCP)
- snprintf(new_option, sizeof(new_option) - 1,
- "mountproto=tcp");
- else
- snprintf(new_option, sizeof(new_option) - 1,
- "mountproto=udp");
- if (po_append(options, new_option) == PO_FAILED)
- goto err;
-
- snprintf(new_option, sizeof(new_option) - 1,
- "mountport=%lu", mnt_server.pmap.pm_port);
- if (po_append(options, new_option) == PO_FAILED)
- goto err;
-
errno = 0;
return options;