diff mbox

libmount: Special handling of root comparison for cifs in mnt_table_is_fs_mounted()

Message ID mpsbn06ruwv.fsf@suse.com (mailing list archive)
State New, archived
Headers show

Commit Message

Aurélien Aptel Sept. 2, 2016, 6:58 p.m. UTC
Hi Stanislav,

I've looked more into it and I found some issues with the patch:

Stanislav Brabec <sbrabec@suse.cz> writes:
> +	while ((c = *subpath++))
                      ^^^ subpath is always post-incremented
> +	{
> +		if (c == '/') {
> +			if (!last_is_slash) {
> +				component_no++;
> +				if (component_no == 3)
> +					break;
                                         ^^^ when we break subpath
                                             actually 1 past the /
> +			}
> +			last_is_slash = true;
> +		} else
> +			last_is_slash = false;
> +	}
> +	if (component_no == 3) {
> +		int subpath_len = strlen(subpath);
> +		if (strncmp(root, subpath, subpath_len)) {
                             ^^^  ^^^ hence why here
with //localhost/share/dir in fstab we never get here
p root    => $1 = 0x7f28aa9977d0 "/dir"
p subpath => $2 = 0x7f28aa9979a2 "dir"

> +			if (*(root + subpath_len + 1) == 0)
> +				return "/";
> +			return root + subpath_len + 1;
> +		}
> +	}
> +	DBG(FS, ul_debugobj(fs, "cifs: leading part of root \"%s\" does
> not equal to mounted source subdir \"%s\"; should not happen", root,
> src));
^^^ this message gets printed with //localhost/share //localhost/share/ 

That being said, I could not make your patch fail i.e. make mount -a
mount the fs twice. So I'm not sure what happens there... I thought I
would give it a try.

I'm attaching a simpler patch that makes uses of streq_paths() in
lib/strutils.c (Note: streq_paths() and next_path_segment() have to be
backported for older versions of util-linux).

Comments

Karel Zak Sept. 29, 2016, 9:55 a.m. UTC | #1
On Fri, Sep 02, 2016 at 08:58:08PM +0200, Aurélien Aptel wrote:
> I'm attaching a simpler patch that makes uses of streq_paths() in
> lib/strutils.c (Note: streq_paths() and next_path_segment() have to be
> backported for older versions of util-linux).
> 
>
> From a29acba1a7c71cdbfc1cc98f2905bfaf19b97a29 Mon Sep 17 00:00:00 2001
> From: Aurelien Aptel <aaptel@suse.com>
> Date: Thu, 1 Sep 2016 13:57:42 +0200
> Subject: [PATCH] libmount/src/tab.c: fix mount -a for cifs

 Applied, thanks!

    Karel
diff mbox

Patch

From a29acba1a7c71cdbfc1cc98f2905bfaf19b97a29 Mon Sep 17 00:00:00 2001
From: Aurelien Aptel <aaptel@suse.com>
Date: Thu, 1 Sep 2016 13:57:42 +0200
Subject: [PATCH] libmount/src/tab.c: fix mount -a for cifs

when mounting a cifs share, the src is actually an UNC path which can in
in several forms:

simple:            //host/share, //host/share/
including subpath: //host/share/sub/path

to check if the cifs fs is mounted we have to extract the subpath and
compare *that* to the root.

Signed-off-by: Aurelien Aptel <aaptel@suse.com>
---
 libmount/src/tab.c | 27 ++++++++++++++++++++++++---
 1 file changed, 24 insertions(+), 3 deletions(-)

diff --git a/libmount/src/tab.c b/libmount/src/tab.c
index 341e5e3..9c49ec8 100644
--- a/libmount/src/tab.c
+++ b/libmount/src/tab.c
@@ -1329,6 +1329,20 @@  err:
 }
 #endif /* HAVE_BTRFS_SUPPORT */
 
+static const char *get_cifs_unc_subdir_path (const char *unc)
+{
+	/*
+	 *  1 or more slash:     %*[/]
+	 *  1 or more non-slash: %*[^/]
+	 *  number of byte read: %n
+	 */
+	int share_end = 0;
+	int r = sscanf(unc, "%*[/]%*[^/]%*[/]%*[^/]%n", &share_end);
+	if (r == EOF || share_end == 0)
+		return NULL;
+	return unc + share_end;
+}
+
 /*
  * tb: /proc/self/mountinfo
  * fs: filesystem
@@ -1563,9 +1577,16 @@  int mnt_table_is_fs_mounted(struct libmnt_table *tb, struct libmnt_fs *fstab_fs)
 		}
 
 		if (root) {
-			const char *r = mnt_fs_get_root(fs);
-			if (!r || strcmp(r, root) != 0)
-				continue;
+			if (strcmp(mnt_fs_get_fstype(fs), "cifs") == 0) {
+				const char *unc_subdir = get_cifs_unc_subdir_path(src);
+				const char *path_on_fs = mnt_fs_get_root(fs);
+				if (!unc_subdir || !path_on_fs || !streq_paths(unc_subdir, path_on_fs))
+					continue;
+			} else {
+				const char *r = mnt_fs_get_root(fs);
+				if (!r || strcmp(r, root) != 0)
+					continue;
+			}
 		}
 
 		/*
-- 
2.1.4