[PATCH cifs-utils] mount.cifs: handle multiple ip addresses per hostname

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Support passing multiple 'ip=' options to specify all ip addresses a
server name was resolved to.

Signed-off-by: Paulo Alcantara (SUSE) <pc@xxxxxx>
---
 mount.cifs.c   | 44 ++++++++++++++++++++------------------------
 mount.cifs.rst |  8 ++++----
 2 files changed, 24 insertions(+), 28 deletions(-)

diff --git a/mount.cifs.c b/mount.cifs.c
index 7f898bbd215a..988e56b649a2 100644
--- a/mount.cifs.c
+++ b/mount.cifs.c
@@ -2036,6 +2036,21 @@ restore_privs:
 	return rc;
 }
 
+static void set_ip_params(char *options, size_t options_size, char *addrlist)
+{
+	char *s = addrlist + strlen(addrlist), *q = s;
+	char tmp;
+
+	do {
+		for (; s >= addrlist && *s != ','; s--);
+		tmp = *q;
+		*q = '\0';
+		strlcat(options, *options ? ",ip=" : "ip=", options_size);
+		strlcat(options, s + 1, options_size);
+		*q = tmp;
+	} while (q = s--, s >= addrlist);
+}
+
 int main(int argc, char **argv)
 {
 	int c;
@@ -2043,7 +2058,6 @@ int main(int argc, char **argv)
 	char *mountpoint = NULL;
 	char *options = NULL;
 	char *orig_dev = NULL;
-	char *currentaddress, *nextaddress;
 	char *value = NULL;
 	char *ep = NULL;
 	int rc = 0;
@@ -2201,20 +2215,10 @@ assemble_retry:
 			goto mount_exit;
 	}
 
-	currentaddress = parsed_info->addrlist;
-	nextaddress = strchr(currentaddress, ',');
-	if (nextaddress)
-		*nextaddress++ = '\0';
-
 mount_retry:
 	options[0] = '\0';
-	if (!currentaddress) {
-		fprintf(stderr, "Unable to find suitable address.\n");
-		rc = parsed_info->nofail ? 0 : EX_FAIL;
-		goto mount_exit;
-	}
-	strlcpy(options, "ip=", options_size);
-	strlcat(options, currentaddress, options_size);
+
+	set_ip_params(options, options_size, parsed_info->addrlist);
 
 	strlcat(options, ",unc=\\\\", options_size);
 	strlcat(options, parsed_info->host, options_size);
@@ -2266,17 +2270,9 @@ mount_retry:
 		switch (errno) {
 		case ECONNREFUSED:
 		case EHOSTUNREACH:
-			if (currentaddress) {
-				fprintf(stderr, "mount error(%d): could not connect to %s",
-					errno, currentaddress);
-			}
-			currentaddress = nextaddress;
-			if (currentaddress) {
-				nextaddress = strchr(currentaddress, ',');
-				if (nextaddress)
-					*nextaddress++ = '\0';
-			}
-			goto mount_retry;
+			fprintf(stderr, "mount error(%d): could not connect to: %s", errno, parsed_info->addrlist);
+			rc = parsed_info->nofail ? 0 : EX_FAIL;
+			break;
 		case ENODEV:
 			fprintf(stderr,
 				"mount error: %s filesystem not supported by the system\n", cifs_fstype);
diff --git a/mount.cifs.rst b/mount.cifs.rst
index 9d4446f035b6..89fb5c902f79 100644
--- a/mount.cifs.rst
+++ b/mount.cifs.rst
@@ -166,10 +166,10 @@ dir_mode=arg
   If the server does not support the CIFS Unix extensions this overrides
   the default mode for directories.
 
-ip=arg|addr=arg
-  sets the destination IP address. This option is set automatically if
-  the server name portion of the requested UNC name can be resolved so
-  rarely needs to be specified by the user.
+ip=arg|addr=arg[,ip=arg2|addr=arg2,...]
+  Sets a maximum number of 16 destination IP addresses. This option is
+  set automatically if the server name portion of the requested UNC
+  name can be resolved so rarely needs to be specified by the user.
 
 domain=arg|dom=arg|workgroup=arg
   Sets the domain (workgroup) of the user. If no domains are given,
-- 
2.31.1




[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux