From b106d052383083b80c0dc41f1555d2661db00374 Mon Sep 17 00:00:00 2001 From: Petr Uzel Date: Tue, 8 Nov 2011 16:25:01 +0100 Subject: [PATCH] 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 --- include/strutils.h | 2 ++ lib/strutils.c | 32 ++++++++++++++++++++++++++++++++ libmount/src/fs.c | 5 +++-- libmount/src/tab.c | 17 ++++++++++++----- libmount/src/tab_parse.c | 11 +++++++++-- mount/fstab.c | 3 ++- 6 files changed, 60 insertions(+), 10 deletions(-) Index: util-linux-2.20.1/include/strutils.h =================================================================== --- util-linux-2.20.1.orig/include/strutils.h +++ util-linux-2.20.1/include/strutils.h @@ -44,4 +44,6 @@ extern int string_to_idarray(const char extern int string_to_bitarray(const char *list, char *ary, int (*name2bit)(const char *, size_t)); +extern int streq_except_trailing_slash(const char *s1, const char *s2); + #endif Index: util-linux-2.20.1/lib/strutils.c =================================================================== --- util-linux-2.20.1.orig/lib/strutils.c +++ util-linux-2.20.1/lib/strutils.c @@ -437,6 +437,40 @@ int string_to_bitarray(const char *list, 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 int main(int argc, char *argv[]) Index: util-linux-2.20.1/libmount/src/fs.c =================================================================== --- util-linux-2.20.1.orig/libmount/src/fs.c +++ util-linux-2.20.1/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 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 /* 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 */ Index: util-linux-2.20.1/libmount/src/tab.c =================================================================== --- util-linux-2.20.1.orig/libmount/src/tab.c +++ util-linux-2.20.1/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 if (path == NULL && src == NULL) return fs; /* source is "none" */ - if (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 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 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 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 libmn *t = mnt_fs_get_target(fs), *r = mnt_fs_get_root(fs); - if (s && t && r && !strcmp(t, tgt) && - !strcmp(s, src) && !strcmp(r, root)) + /* + * Note that kernel can add tailing slash to the + * network filesystem source paths. + */ + if (t && s && r && + strcmp(t, tgt) == 0 && + streq_except_trailing_slash(s, src) && + strcmp(r, root) == 0) break; } if (fs) Index: util-linux-2.20.1/libmount/src/tab_parse.c =================================================================== --- util-linux-2.20.1.orig/libmount/src/tab_parse.c +++ util-linux-2.20.1/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 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; } Index: util-linux-2.20.1/mount/fstab.c =================================================================== --- util-linux-2.20.1.orig/mount/fstab.c +++ util-linux-2.20.1/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 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); } }