From: Petr Uzel Date: Tue, 8 Nov 2011 15:25:01 +0000 (+0100) Subject: libmount: ignore tailing slash in netfs source paths X-Git-Tag: v2.21-rc1~213 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b106d052383083b80c0dc41f1555d2661db00374;p=thirdparty%2Futil-linux.git libmount: ignore tailing slash in netfs source paths Addresses: https://bugzilla.novell.com/show_bug.cgi?id=728480 Signed-off-by: Petr Uzel Signed-off-by: Karel Zak --- diff --git a/include/strutils.h b/include/strutils.h index 9765a77477..ef283dfed7 100644 --- a/include/strutils.h +++ b/include/strutils.h @@ -47,4 +47,6 @@ extern int string_to_bitarray(const char *list, char *ary, extern int parse_range(const char *str, int *lower, int *upper, int def); +extern int streq_except_trailing_slash(const char *s1, const char *s2); + #endif diff --git a/lib/strutils.c b/lib/strutils.c index 6b2ec799e7..75861607e5 100644 --- a/lib/strutils.c +++ b/lib/strutils.c @@ -504,6 +504,38 @@ int parse_range(const char *str, int *lower, int *upper, int def) return 0; } +/* + * Compare two strings for equality, ignoring at most one trailing + * slash. + */ +int streq_except_trailing_slash(const char *s1, const char *s2) +{ + int equal; + + if (!s1 && !s2) + return 1; + if (!s1 || !s2) + return 0; + + equal = !strcmp(s1, s2); + + if (!equal) { + size_t len1 = strlen(s1); + size_t len2 = strlen(s2); + + if (len1 && *(s1 + len1 - 1) == '/') + len1--; + if (len2 && *(s2 + len2 - 1) == '/') + len2--; + if (len1 != len2) + return 0; + + equal = !strncmp(s1, s2, len1); + } + + return equal; +} + #ifdef TEST_PROGRAM diff --git a/libmount/src/fs.c b/libmount/src/fs.c index 1c7068dd0c..26560d161a 100644 --- a/libmount/src/fs.c +++ b/libmount/src/fs.c @@ -16,6 +16,7 @@ #include #include "mountP.h" +#include "strutils.h" /** * mnt_new_fs: @@ -1142,7 +1143,7 @@ int mnt_fs_match_source(struct libmnt_fs *fs, const char *source, struct libmnt_ return 0; /* 1) native paths/tags */ - if (!strcmp(source, fs->source)) + if (streq_except_trailing_slash(source, fs->source)) return 1; if (!cache) @@ -1156,7 +1157,7 @@ int mnt_fs_match_source(struct libmnt_fs *fs, const char *source, struct libmnt_ /* 2) canonicalized and native */ src = mnt_fs_get_srcpath(fs); - if (src && !strcmp(cn, src)) + if (src && streq_except_trailing_slash(cn, src)) return 1; /* 3) canonicalized and canonicalized */ diff --git a/libmount/src/tab.c b/libmount/src/tab.c index c06409d290..2bc49e3b7a 100644 --- a/libmount/src/tab.c +++ b/libmount/src/tab.c @@ -44,6 +44,7 @@ #include #include "mountP.h" +#include "strutils.h" /** * mnt_new_table: @@ -506,7 +507,7 @@ struct libmnt_fs *mnt_table_find_srcpath(struct libmnt_table *tb, const char *pa if (path == NULL && src == NULL) return fs; /* source is "none" */ - if (path && p && strcmp(p, path) == 0) + if (path && p && streq_except_trailing_slash(p, path)) return fs; if (!p && src) ntags++; /* mnt_fs_get_srcpath() returs nothing, it's TAG */ @@ -520,7 +521,7 @@ struct libmnt_fs *mnt_table_find_srcpath(struct libmnt_table *tb, const char *pa mnt_reset_iter(&itr, direction); while(mnt_table_next_fs(tb, &itr, &fs) == 0) { p = mnt_fs_get_srcpath(fs); - if (p && strcmp(p, cn) == 0) + if (p && streq_except_trailing_slash(p, cn)) return fs; } } @@ -551,7 +552,7 @@ struct libmnt_fs *mnt_table_find_srcpath(struct libmnt_table *tb, const char *pa if (mnt_fs_get_tag(fs, &t, &v)) continue; x = mnt_resolve_tag(t, v, tb->cache); - if (x && !strcmp(x, cn)) + if (x && streq_except_trailing_slash(x, cn)) return fs; } } @@ -566,7 +567,7 @@ struct libmnt_fs *mnt_table_find_srcpath(struct libmnt_table *tb, const char *pa p = mnt_fs_get_srcpath(fs); if (p) p = mnt_resolve_path(p, tb->cache); - if (p && strcmp(cn, p) == 0) + if (p && streq_except_trailing_slash(cn, p)) return fs; } } @@ -856,8 +857,14 @@ int mnt_table_is_fs_mounted(struct libmnt_table *tb, struct libmnt_fs *fstab_fs) *t = mnt_fs_get_target(fs), *r = mnt_fs_get_root(fs); + /* + * Note that kernel can add tailing slash to the + * network filesystem source paths. + */ if (t && s && r && - !strcmp(t, tgt) && !strcmp(s, src) && !strcmp(r, root)) + strcmp(t, tgt) == 0 && + streq_except_trailing_slash(s, src) && + strcmp(r, root) == 0) break; } if (fs) diff --git a/libmount/src/tab_parse.c b/libmount/src/tab_parse.c index 18a1243459..4ee5908899 100644 --- a/libmount/src/tab_parse.c +++ b/libmount/src/tab_parse.c @@ -14,6 +14,7 @@ #include "mangle.h" #include "mountP.h" #include "pathnames.h" +#include "strutils.h" static inline char *skip_spaces(char *s) { @@ -654,8 +655,14 @@ static struct libmnt_fs *mnt_table_merge_user_fs(struct libmnt_table *tb, struct if (fs->flags & MNT_FS_MERGED) continue; - if (s && t && r && !strcmp(t, target) && - !strcmp(s, src) && !strcmp(r, root)) + /* + * Note that kernel can add tailing slash to the network + * filesystem source path + */ + if (s && t && r && + strcmp(t, target) == 0 && + streq_except_trailing_slash(s, src) && + strcmp(r, root) == 0) break; } diff --git a/mount/fstab.c b/mount/fstab.c index 078401cccc..a1bae908ea 100644 --- a/mount/fstab.c +++ b/mount/fstab.c @@ -20,6 +20,7 @@ #include "pathnames.h" #include "nls.h" #include "usleep.h" +#include "strutils.h" #define streq(s, t) (strcmp ((s), (t)) == 0) @@ -436,7 +437,7 @@ getfs_by_devdir (const char *dev, const char *dir) { ok = has_uuid(dev, fs + 5); } else { fs = canonicalize_spec(mc->m.mnt_fsname); - ok = streq(fs, dev); + ok = streq_except_trailing_slash(fs, dev); my_free(fs); } }