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 */