Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 5015fa13114323005d44384f3f7a174e > files > 83

autofs-5.0.1-0.rc2.156.el5.src.rpm

autofs-5.0.1 - handle colon in Lustre failover mounts

From: Ian Kent <raven@themaw.net>

Lustre MDT failover mountpoints have a syntax like
172.21.48.22@tcp:172.21.48.21@tcp:/ana1, and the embedded colon causes
autofs incorrectly think it has seen all the portion of the mount entry
before the path when it hasn't.
---

 lib/parse_subs.c     |   11 +++++------
 modules/parse_sun.c  |   16 +++++++++-------
 modules/replicated.c |   26 ++++++++++++++++++++++++--
 3 files changed, 38 insertions(+), 15 deletions(-)


diff --git a/lib/parse_subs.c b/lib/parse_subs.c
index 3a04dd6..b7025ad 100644
--- a/lib/parse_subs.c
+++ b/lib/parse_subs.c
@@ -57,14 +57,13 @@ int check_colon(const char *str)
 	char *ptr = (char *) str;
 
 	/* Colon escape */
-	if (*ptr == ':')
+	if (!strncmp(ptr, ":/", 2))
 		return 1;
 
-	while (*ptr && *ptr != ':' && *ptr != '/') {
+	while (*ptr && strncmp(ptr, ":/", 2))
 		ptr++;
-	}
 
-	if (!*ptr || *ptr == '/')
+	if (!*ptr)
 		return 0;
 
 	return 1;
@@ -94,12 +93,12 @@ int chunklen(const char *whence, int expect_colon)
 				n++;
 				if (*str == '"')
 					break;
-				if (*str == ':')
+				if (!strncmp(str, ":/", 2))
 					expect_colon = 0;
 			}
 			break;
 		case ':':
-			if (expect_colon)
+			if (expect_colon && !strncmp(str, ":/", 2))
 				expect_colon = 0;
 			continue;
 		case ' ':
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index d6aa3f4..ad62ff6 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -263,7 +263,9 @@ int expandsunent(const char *src, char *dst, const char *key,
 				*(dst++) = 
 				  (seen_colons && slashify_colons) ? '/' : ':';
 			len++;
-			seen_colons = 1;
+			/* Were looking for the colon preceeding a path */
+			if (*src == '/')
+				seen_colons = 1;
 			break;
 
 		default:
@@ -861,21 +863,21 @@ static int validate_location(char *loc)
 		return 1;
 
 	/*
-	 * If a ':' is present now it must be a host name, except
-	 * for those special file systems like sshfs which use "#"
-	 * and "@" in the host name part.
+	 * If a ':/' is present now it must be a host name, except
+	 * for those special file systems like sshfs which use "#",
+	 * "@" and ":" in the host name part.
 	 */
 	if (check_colon(ptr)) {
-		while (*ptr && *ptr != ':') {
+		while (*ptr && strncmp(ptr, ":/", 2)) {
 			if (!(isalnum(*ptr) ||
 			    *ptr == '-' || *ptr == '.' || *ptr == '_' ||
 			    *ptr == ',' || *ptr == '(' || *ptr == ')' ||
-			    *ptr == '#' || *ptr == '@'))
+			    *ptr == '#' || *ptr == '@' || *ptr == ':'))
 				return 0;
 			ptr++;
 		}
 
-		if (*ptr && *ptr == ':')
+		if (*ptr && !strncmp(ptr, ":/", 2))
 			ptr++;
 	}
 
diff --git a/modules/replicated.c b/modules/replicated.c
index 4848620..5e6d20a 100644
--- a/modules/replicated.c
+++ b/modules/replicated.c
@@ -1128,6 +1128,28 @@ static int add_local_path(struct host **hosts, const char *path)
 	return 1;
 }
 
+static char *seek_delim(const char *s)
+{
+	const char *p = s;
+	char *delim;
+
+	delim = strpbrk(p, "(, \t:");
+	if (delim && *delim != ':')
+		return delim;
+
+	while (*p) {
+		if (*p != ':') {
+			p++;
+			continue;
+		}
+		if (!strncmp(p, ":/", 2))
+			return (char *) p;
+		p++;
+	}
+
+	return NULL;
+}
+
 int parse_location(unsigned logopt, struct host **hosts,
 		   const char *list, unsigned int options)
 {
@@ -1148,7 +1170,7 @@ int parse_location(unsigned logopt, struct host **hosts,
 		int weight = 0;
 
 		p += strspn(p, " \t,");
-		delim = strpbrk(p, "(, \t:");
+		delim = seek_delim(p);
 
 		if (delim) {
 			if (*delim == '(') {
@@ -1172,7 +1194,7 @@ int parse_location(unsigned logopt, struct host **hosts,
 
 				/* Oh boy - might have spaces in the path */
 				next = path;
-				while (*next && *next != ':')
+				while (*next && strncmp(next, ":/", 2))
 					next++;
 
 				/* No spaces in host names at least */