From c59cf20c1be6d78f4e9ef404f5c5f2d44d57df94 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Mon, 10 Jan 2011 14:29:51 +0100 Subject: [PATCH] libmount: properly canonicalize source and target Signed-off-by: Karel Zak --- shlibs/mount/src/cache.c | 7 ++++ shlibs/mount/src/context.c | 68 +++++++++++++++++++++++-------- shlibs/mount/src/context_mount.c | 2 + shlibs/mount/src/context_umount.c | 2 + shlibs/mount/src/mountP.h | 1 + shlibs/mount/src/utils.c | 9 ++-- 6 files changed, 68 insertions(+), 21 deletions(-) diff --git a/shlibs/mount/src/cache.c b/shlibs/mount/src/cache.c index 3ed69e1b..9e20a2ae 100644 --- a/shlibs/mount/src/cache.c +++ b/shlibs/mount/src/cache.c @@ -406,6 +406,8 @@ char *mnt_get_fstype(const char *devname, int *ambi, mnt_cache *cache) char *type = NULL; int rc; + DBG(CACHE, mnt_debug_h(cache, "get %s FS type", devname)); + if (cache) return mnt_cache_find_tag_value(cache, devname, "TYPE"); @@ -444,6 +446,8 @@ char *mnt_resolve_path(const char *path, mnt_cache *cache) assert(path); + DBG(CACHE, mnt_debug_h(cache, "resolving path %s", path)); + if (!path) return NULL; if (cache) @@ -489,6 +493,9 @@ char *mnt_resolve_tag(const char *token, const char *value, mnt_cache *cache) assert(token); assert(value); + DBG(CACHE, mnt_debug_h(cache, "resolving tag token=%s value=%s", + token, value)); + if (!token || !value) return NULL; diff --git a/shlibs/mount/src/context.c b/shlibs/mount/src/context.c index deeb606c..82a47a0e 100644 --- a/shlibs/mount/src/context.c +++ b/shlibs/mount/src/context.c @@ -843,7 +843,7 @@ int mnt_context_set_mountdata(mnt_context *cxt, void *data) */ int mnt_context_prepare_srcpath(mnt_context *cxt) { - const char *path = NULL, *type; + const char *path = NULL; mnt_cache *cache; const char *t, *v, *src; int rc = 0; @@ -859,16 +859,15 @@ int mnt_context_prepare_srcpath(mnt_context *cxt) src = mnt_fs_get_source(cxt->fs); - /* ignore filesystems without a real source or MS_PROPAGATION stuff */ - if (!src || - (cxt->fs->flags & (MNT_FS_PSEUDO | MNT_FS_NET)) || - (cxt->mountflags & (MS_BIND | MS_MOVE | MS_PROPAGATION))) + /* ignore filesystems without source or filesystems + * where the source is quasi-path (//foo/bar) + */ + if (!src || (cxt->fs->flags & MNT_FS_NET)) return 0; DBG(CXT, mnt_debug_h(cxt, "srcpath '%s'", src)); cache = mnt_context_get_cache(cxt); - type = mnt_fs_get_fstype(cxt->fs); if (!mnt_fs_get_tag(cxt->fs, &t, &v)) { /* @@ -879,28 +878,29 @@ int mnt_context_prepare_srcpath(mnt_context *cxt) rc = path ? mnt_fs_set_source(cxt->fs, path) : -EINVAL; - } else if (!type || (strncmp(type, "9p", 2) && - strncmp(type, "nfs", 3) && - strncmp(type, "cifs", 4) && - strncmp(type, "smbfs", 5))) { + } else if (cache) { /* * Source is PATH (canonicalize) */ - if (cache) { - path = mnt_resolve_path(src, cache); - if (strcmp(path, src)) - rc = mnt_fs_set_source(cxt->fs, path); - } - } + path = mnt_resolve_path(src, cache); + if (path && strcmp(path, src)) + rc = mnt_fs_set_source(cxt->fs, path); + } if (rc) { - DBG(CXT, mnt_debug_h(cxt, "failed to prepare srcpath")); + DBG(CXT, mnt_debug_h(cxt, "failed to prepare srcpath [rc=%d]", rc)); return rc; } if (!path) path = src; + if ((cxt->mountflags & (MS_BIND | MS_MOVE | MS_PROPAGATION)) || + (cxt->fs->flags & MNT_FS_PSEUDO)) { + DBG(CXT, mnt_debug_h(cxt, "PROPAGATION/pseudo FS source: %s", path)); + return rc; + } + /* * Initialize loop device */ @@ -912,6 +912,40 @@ int mnt_context_prepare_srcpath(mnt_context *cxt) return 0; } +int mnt_context_prepare_target(mnt_context *cxt) +{ + const char *tgt; + mnt_cache *cache; + int rc = 0; + + assert(cxt); + assert(cxt->fs); + assert((cxt->flags & MNT_FL_MOUNTFLAGS_MERGED)); + + if (!cxt || !cxt->fs) + return -EINVAL; + + DBG(CXT, mnt_debug_h(cxt, "preparing target path")); + + tgt = mnt_fs_get_target(cxt->fs); + if (!tgt) + return 0; + + cache = mnt_context_get_cache(cxt); + if (cache) { + char *path = mnt_resolve_path(tgt, cache); + if (strcmp(path, tgt)) + rc = mnt_fs_set_target(cxt->fs, path); + } + + if (rc) + DBG(CXT, mnt_debug_h(cxt, "failed to prepare target")); + else + DBG(CXT, mnt_debug_h(cxt, "final target '%s'", + mnt_fs_get_target(cxt->fs))); + return 0; +} + int mnt_context_guess_fstype(mnt_context *cxt) { char *type; diff --git a/shlibs/mount/src/context_mount.c b/shlibs/mount/src/context_mount.c index 574a8142..5f6ba696 100644 --- a/shlibs/mount/src/context_mount.c +++ b/shlibs/mount/src/context_mount.c @@ -453,6 +453,8 @@ int mnt_context_do_mount(mnt_context *cxt) rc = fix_optstr(cxt); if (!rc) rc = mnt_context_prepare_srcpath(cxt); + if (!rc) + rc = mnt_context_prepare_target(cxt); if (!rc) rc = mnt_context_guess_fstype(cxt); if (!rc) diff --git a/shlibs/mount/src/context_umount.c b/shlibs/mount/src/context_umount.c index 9bbdc29a..9b411d86 100644 --- a/shlibs/mount/src/context_umount.c +++ b/shlibs/mount/src/context_umount.c @@ -469,6 +469,8 @@ int mnt_context_do_umount(mnt_context *cxt) rc = mnt_context_merge_mountflags(cxt); if (!rc) rc = evaluate_permissions(cxt); + if (!rc) + rc = mnt_context_prepare_target(cxt); if (!rc && !cxt->helper) rc = mnt_context_prepare_helper(cxt, "umount", NULL); /* TODO diff --git a/shlibs/mount/src/mountP.h b/shlibs/mount/src/mountP.h index f9e3a3f7..c1a864ae 100644 --- a/shlibs/mount/src/mountP.h +++ b/shlibs/mount/src/mountP.h @@ -310,6 +310,7 @@ extern int __mnt_fs_set_fstype_ptr(mnt_fs *fs, char *fstype); /* context.c */ extern int mnt_context_prepare_srcpath(mnt_context *cxt); +extern int mnt_context_prepare_target(mnt_context *cxt); extern int mnt_context_guess_fstype(mnt_context *cxt); extern int mnt_context_prepare_helper(mnt_context *cxt, const char *name, const char *type); extern int mnt_context_prepare_update(mnt_context *cxt); diff --git a/shlibs/mount/src/utils.c b/shlibs/mount/src/utils.c index 99708333..48c37de3 100644 --- a/shlibs/mount/src/utils.c +++ b/shlibs/mount/src/utils.c @@ -137,11 +137,12 @@ int mnt_fstype_is_netfs(const char *type) { if (!type) return 0; - if (strcmp(type, "cifs") == 0 || + if (strcmp(type, "cifs") == 0 || strcmp(type, "smbfs") == 0 || - strncmp(type, "nfs", 3) == 0 || - strcmp(type, "afs") == 0 || - strcmp(type, "ncpfs") == 0) + strncmp(type,"nfs", 3) == 0 || + strcmp(type, "afs") == 0 || + strcmp(type, "ncpfs") == 0 || + strncmp(type,"9p", 2) == 0) return 1; return 0; } -- 2.39.5