diff mbox

Btrfs-progs: replace find_mount_root from send code

Message ID 1345463835-26636-1-git-send-email-list.btrfs@jan-o-sch.net (mailing list archive)
State New, archived
Headers show

Commit Message

Jan Schmidt Aug. 20, 2012, 11:57 a.m. UTC
Hi Robert,

i made a quick patch, can you please give it a try? Can be applied with
"git am --scissors".

Thanks,
-Jan

-- >8 --

find_mount_root had the problem that it tried to conclude from a file system
path to a mount point, taking the fsid as an indicator. This only works if
no two subvolumes (sharing the same btrfs fsid) are mounted in the same
hierarchy.

Now instead, we're parsing /etc/mtab and look for the longest match.

Signed-off-by: Jan Schmidt <list.btrfs@jan-o-sch.net>
---
 cmds-send.c |   88 ++++++++++++++---------------------------------------------
 1 files changed, 21 insertions(+), 67 deletions(-)

Comments

Robert Buhren Aug. 23, 2012, 8:54 a.m. UTC | #1
Hi Jan,


thanks for the patch! Sending works. But i got some trouble on the 
receiving side.
Here's my complete test-setup:


I have two btrfs partitions:

mount | grep btrfs:

/dev/loop0 on /mnt/TEST_ROOT type btrfs 
(rw,relatime,compress=lzo,space_cache)  # default-subvolume
/dev/loop0 on /mnt/TEST_ROOT/root_volid0 type btrfs 
(rw,relatime,compress=lzo,space_cache) # subvolid= 0
/dev/loop1 on /mnt/TEST_ROOT/backup_volid0 type btrfs 
(rw,relatime,compress=lzo,space_cache)

With the patch this works now:

btrfs subvolume snapshot -r /mnt/TEST_ROOT/root_volid0/root/ 
/mnt/TEST_ROOT/root_volid0/root_snap
btrfs send /mnt/TEST_ROOT/root_volid0/root_snap > root_snap_send

But when i try to receive it on the /mnt/TEST_ROOT/backup_volid0 btrfs 
partition i get:

btrfs receive -f root_snap_send /mnt/TEST_ROOT/backup_volid0/
     ERROR: utimes  failed. Bad file descriptor

i also tried  "cat root_snap_send | btrfs receive 
/mnt/TEST_ROOT/backup_volid0". But the result is the same.
What's interesting is that there is actually a subvolume "root_snap" 
created in "backup_volid0", but it's empty.

I'm on linux-3.6-rc2 and btrfs-progs from git.

If further Information is needed, just tell me.


Regards,

Robert






On 20.08.2012 13:57, Jan Schmidt wrote:
> Hi Robert,
>
> i made a quick patch, can you please give it a try? Can be applied with
> "git am --scissors".
>
> Thanks,
> -Jan
>
> -- >8 --
>
> find_mount_root had the problem that it tried to conclude from a file system
> path to a mount point, taking the fsid as an indicator. This only works if
> no two subvolumes (sharing the same btrfs fsid) are mounted in the same
> hierarchy.
>
> Now instead, we're parsing /etc/mtab and look for the longest match.
>
> Signed-off-by: Jan Schmidt <list.btrfs@jan-o-sch.net>
> ---
>   cmds-send.c |   88 ++++++++++++++---------------------------------------------
>   1 files changed, 21 insertions(+), 67 deletions(-)
>
> diff --git a/cmds-send.c b/cmds-send.c
> index 8a0c110..41ea523 100644
> --- a/cmds-send.c
> +++ b/cmds-send.c
> @@ -28,6 +28,7 @@
>   #include <sys/types.h>
>   #include <sys/ioctl.h>
>   #include <libgen.h>
> +#include <mntent.h>
>
>   #include <uuid/uuid.h>
>
> @@ -55,82 +56,35 @@ struct btrfs_send {
>
>   int find_mount_root(const char *path, char **mount_root)
>   {
> -	int ret;
> -	char *cur;
> -	char fsid[BTRFS_FSID_SIZE];
> +	FILE *mnttab;
>   	int fd;
> -	struct stat st;
> -	char *tmp;
> -	char *dup = NULL;
> -
> -	struct btrfs_ioctl_fs_info_args args;
> +	struct mntent *ent;
> +	int len;
> +	int longest_matchlen = 0;
> +	char *longest_match = NULL;
>
>   	fd = open(path, O_RDONLY | O_NOATIME);
> -	if (fd < 0) {
> -		ret = -errno;
> -		goto out;
> -	}
> -
> -	ret = fstat(fd, &st);
> -	if (fd < 0) {
> -		ret = -errno;
> -		goto out;
> -	}
> -	if (!S_ISDIR(st.st_mode)) {
> -		ret = -ENOTDIR;
> -		goto out;
> -	}
> -
> -	ret = ioctl(fd, BTRFS_IOC_FS_INFO, &args);
> -	if (fd < 0) {
> -		ret = -errno;
> -		goto out;
> -	}
> -	memcpy(fsid, args.fsid, BTRFS_FSID_SIZE);
> +	if (fd < 0)
> +		return -errno;
>   	close(fd);
> -	fd = -1;
>
> -	cur = strdup(path);
> -
> -	while (1) {
> -		dup = strdup(cur);
> -		tmp = dirname(dup);
> -
> -		if (!tmp)
> -			break;
> -		fd = open(tmp, O_RDONLY | O_NOATIME);
> -		if (fd < 0) {
> -			ret = -errno;
> -			goto out;
> +	mnttab = fopen("/etc/mtab", "r");
> +	while ((ent = getmntent(mnttab))) {
> +		len = strlen(ent->mnt_dir);
> +		if (strncmp(ent->mnt_dir, path, len) == 0) {
> +			/* match found */
> +			if (longest_matchlen < len) {
> +				free(longest_match);
> +				longest_matchlen = len;
> +				longest_match = strdup(ent->mnt_dir);
> +			}
>   		}
> -
> -		ret = ioctl(fd, BTRFS_IOC_FS_INFO, &args);
> -		close(fd);
> -		fd = -1;
> -		if (ret < 0)
> -			break;
> -		if (memcmp(fsid, args.fsid, BTRFS_FSID_SIZE) != 0)
> -			break;
> -
> -		free(cur);
> -		cur = strdup(tmp);
> -		free(dup);
> -		dup = NULL;
> -		if (strcmp(cur, "/") == 0)
> -			break;
> -		if (strcmp(cur, ".") == 0)
> -			break;
>   	}
>
> -	ret = 0;
> -	*mount_root = realpath(cur, NULL);
> +	*mount_root = realpath(longest_match, NULL);
> +	free(longest_match);
>
> -out:
> -	if (dup)
> -		free(dup);
> -	if (fd != -1)
> -		close(fd);
> -	return ret;
> +	return 0;
>   }
>
>   static int get_root_id(struct btrfs_send *s, const char *path, u64 *root_id)


--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
David Sterba Aug. 24, 2012, 1:33 p.m. UTC | #2
On Thu, Aug 23, 2012 at 10:54:54AM +0200, Robert Buhren wrote:
> I'm on linux-3.6-rc2 and btrfs-progs from git.

Please try it with Chris' for-linus branch, it contains a fair portion
of send-related fixes and from brief look they may be related to the
errors you see.

david
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Robert Buhren Aug. 25, 2012, 8:24 a.m. UTC | #3
On 24.08.2012 15:33, David Sterba wrote:
> On Thu, Aug 23, 2012 at 10:54:54AM +0200, Robert Buhren wrote:
>> I'm on linux-3.6-rc2 and btrfs-progs from git.
> Please try it with Chris' for-linus branch, it contains a fair portion
> of send-related fixes and from brief look they may be related to the
> errors you see.
>
> david
Hi David,

i just tried it with a kernel from the "for-linus" branch. But i still 
get the same error.
Just to be sure:
You ment this branch: 
http://git.kernel.org/?p=linux/kernel/git/mason/linux-btrfs.git;a=shortlog;h=refs/heads/for-linus

right?


Regards,

Robert
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Alex Lyakas Aug. 27, 2012, 9:16 a.m. UTC | #4
Hi Robert,
do you think you can make the "root_snap_send" file of yours available
anywhere (not sure how big it is)?

Also, I am not sure I understand how you btrfs tree looks like WRT to
where all subvolumes are mounted (but all others seem to understand
well).

You mentioned:
> /dev/loop0 on /mnt/TEST_ROOT type btrfs (rw,relatime,compress=lzo,space_cache)  # default-subvolume
> /dev/loop0 on /mnt/TEST_ROOT/root_volid0 type btrfs (rw,relatime,compress=lzo,space_cache) # subvolid= 0
> /dev/loop1 on /mnt/TEST_ROOT/backup_volid0 type btrfs (rw,relatime,compress=lzo,space_cache)

> btrfs subvolume snapshot -r /mnt/TEST_ROOT/root_volid0/root/ /mnt/TEST_ROOT/root_volid0/root_snap
Are you trying to snapshot a directory here? I.e., what is "root"
within "root_volid0"?
Can you pls list all subvolumes you have on your source filesystem
(the one you are trying to backup), and where each one is mounted?
Again, looks like I'm the only one confused about this, so apologies.

You can also possibly use the "tree" utility to better visualize your
fs tree, like:
tree -A  --inodes --noreport /mnt/TEST_ROOT

Jan, David, hope it's ok with you if I'll try to debug this.

Thanks,
Alex.






On Sat, Aug 25, 2012 at 11:24 AM, Robert Buhren <robert@robertbuhren.de> wrote:
> On 24.08.2012 15:33, David Sterba wrote:
>>
>> On Thu, Aug 23, 2012 at 10:54:54AM +0200, Robert Buhren wrote:
>>>
>>> I'm on linux-3.6-rc2 and btrfs-progs from git.
>>
>> Please try it with Chris' for-linus branch, it contains a fair portion
>> of send-related fixes and from brief look they may be related to the
>> errors you see.
>>
>> david
>
> Hi David,
>
> i just tried it with a kernel from the "for-linus" branch. But i still get
> the same error.
> Just to be sure:
> You ment this branch:
> http://git.kernel.org/?p=linux/kernel/git/mason/linux-btrfs.git;a=shortlog;h=refs/heads/for-linus
>
> right?
>
>
> Regards,
>
> Robert
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Robert Buhren Aug. 27, 2012, 6:37 p.m. UTC | #5
Hi Alex,

i've made a list of all commands i executed for this test. You can find 
it here:

http://pastebin.com/y8PBgmMZ


> Hi Robert,
> do you think you can make the "root_snap_send" file of yours available
> anywhere (not sure how big it is)?
I'm afraid i've already delete it :/ sry. But in the pastebin there 
should be all the commands
you need to execute to reproduce my setup.
>
> Also, I am not sure I understand how you btrfs tree looks like WRT to
> where all subvolumes are mounted (but all others seem to understand
> well).
>
> You mentioned:
>> /dev/loop0 on /mnt/TEST_ROOT type btrfs (rw,relatime,compress=lzo,space_cache)  # default-subvolume
>> /dev/loop0 on /mnt/TEST_ROOT/root_volid0 type btrfs (rw,relatime,compress=lzo,space_cache) # subvolid= 0
>> /dev/loop1 on /mnt/TEST_ROOT/backup_volid0 type btrfs (rw,relatime,compress=lzo,space_cache)
>> btrfs subvolume snapshot -r /mnt/TEST_ROOT/root_volid0/root/ /mnt/TEST_ROOT/root_volid0/root_snap
> Are you trying to snapshot a directory here? I.e., what is "root"
> within "root_volid0"?
root is a subvolume inside the /dev/loop0 fs. It is set as the default 
subvolume.
I mounted /dev/loop0 at /mnt/TEST_ROOT and inside that i mounted 
/dev/loop0 again,
but this time with subvolid=0. So "/mnt/TEST_ROOT/root_volid0/root" is 
actually a subvolume
which is also mounted at "/mnt/TEST_ROOT".
> Can you pls list all subvolumes you have on your source filesystem
> (the one you are trying to backup), and where each one is mounted?
> Again, looks like I'm the only one confused about this, so apologies.
>
> You can also possibly use the "tree" utility to better visualize your
> fs tree, like:
> tree -A  --inodes --noreport /mnt/TEST_ROOT
>
> Jan, David, hope it's ok with you if I'll try to debug this.
>
> Thanks,
> Alex.
>
I'm kinda in a hurry now because i'm leaving for Holidays soon and i 
still have to finish my bachelor thesis :P

I hope with the the commands from the pastebin you have everything you 
need. I can answer emails until Friday morning.

Regards,

Robert


>
>
>
>
> On Sat, Aug 25, 2012 at 11:24 AM, Robert Buhren <robert@robertbuhren.de> wrote:
>> On 24.08.2012 15:33, David Sterba wrote:
>>> On Thu, Aug 23, 2012 at 10:54:54AM +0200, Robert Buhren wrote:
>>>> I'm on linux-3.6-rc2 and btrfs-progs from git.
>>> Please try it with Chris' for-linus branch, it contains a fair portion
>>> of send-related fixes and from brief look they may be related to the
>>> errors you see.
>>>
>>> david
>> Hi David,
>>
>> i just tried it with a kernel from the "for-linus" branch. But i still get
>> the same error.
>> Just to be sure:
>> You ment this branch:
>> http://git.kernel.org/?p=linux/kernel/git/mason/linux-btrfs.git;a=shortlog;h=refs/heads/for-linus
>>
>> right?
>>
>>
>> Regards,
>>
>> Robert
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html

--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Alex Lyakas Aug. 28, 2012, 8:27 a.m. UTC | #6
Thank you, Robert for the detailed data. I will debug & get back to
you before Friday.

Alex.


On Mon, Aug 27, 2012 at 9:37 PM, Robert Buhren <robert@robertbuhren.de> wrote:
> Hi Alex,
>
> i've made a list of all commands i executed for this test. You can find it
> here:
>
> http://pastebin.com/y8PBgmMZ
>
>
>
>> Hi Robert,
>> do you think you can make the "root_snap_send" file of yours available
>> anywhere (not sure how big it is)?
>
> I'm afraid i've already delete it :/ sry. But in the pastebin there should
> be all the commands
> you need to execute to reproduce my setup.
>
>>
>> Also, I am not sure I understand how you btrfs tree looks like WRT to
>> where all subvolumes are mounted (but all others seem to understand
>> well).
>>
>> You mentioned:
>>>
>>> /dev/loop0 on /mnt/TEST_ROOT type btrfs
>>> (rw,relatime,compress=lzo,space_cache)  # default-subvolume
>>> /dev/loop0 on /mnt/TEST_ROOT/root_volid0 type btrfs
>>> (rw,relatime,compress=lzo,space_cache) # subvolid= 0
>>> /dev/loop1 on /mnt/TEST_ROOT/backup_volid0 type btrfs
>>> (rw,relatime,compress=lzo,space_cache)
>>> btrfs subvolume snapshot -r /mnt/TEST_ROOT/root_volid0/root/
>>> /mnt/TEST_ROOT/root_volid0/root_snap
>>
>> Are you trying to snapshot a directory here? I.e., what is "root"
>> within "root_volid0"?
>
> root is a subvolume inside the /dev/loop0 fs. It is set as the default
> subvolume.
> I mounted /dev/loop0 at /mnt/TEST_ROOT and inside that i mounted /dev/loop0
> again,
> but this time with subvolid=0. So "/mnt/TEST_ROOT/root_volid0/root" is
> actually a subvolume
> which is also mounted at "/mnt/TEST_ROOT".
>
>> Can you pls list all subvolumes you have on your source filesystem
>> (the one you are trying to backup), and where each one is mounted?
>> Again, looks like I'm the only one confused about this, so apologies.
>>
>> You can also possibly use the "tree" utility to better visualize your
>> fs tree, like:
>> tree -A  --inodes --noreport /mnt/TEST_ROOT
>>
>> Jan, David, hope it's ok with you if I'll try to debug this.
>>
>> Thanks,
>> Alex.
>>
> I'm kinda in a hurry now because i'm leaving for Holidays soon and i still
> have to finish my bachelor thesis :P
>
> I hope with the the commands from the pastebin you have everything you need.
> I can answer emails until Friday morning.
>
> Regards,
>
> Robert
>
>
>
>>
>>
>>
>>
>> On Sat, Aug 25, 2012 at 11:24 AM, Robert Buhren <robert@robertbuhren.de>
>> wrote:
>>>
>>> On 24.08.2012 15:33, David Sterba wrote:
>>>>
>>>> On Thu, Aug 23, 2012 at 10:54:54AM +0200, Robert Buhren wrote:
>>>>>
>>>>> I'm on linux-3.6-rc2 and btrfs-progs from git.
>>>>
>>>> Please try it with Chris' for-linus branch, it contains a fair portion
>>>> of send-related fixes and from brief look they may be related to the
>>>> errors you see.
>>>>
>>>> david
>>>
>>> Hi David,
>>>
>>> i just tried it with a kernel from the "for-linus" branch. But i still
>>> get
>>> the same error.
>>> Just to be sure:
>>> You ment this branch:
>>>
>>> http://git.kernel.org/?p=linux/kernel/git/mason/linux-btrfs.git;a=shortlog;h=refs/heads/for-linus
>>>
>>> right?
>>>
>>>
>>> Regards,
>>>
>>> Robert
>>>
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
>>> the body of a message to majordomo@vger.kernel.org
>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Alex Lyakas Oct. 3, 2012, 1:01 p.m. UTC | #7
Hi Jan,

> +       mnttab = fopen("/etc/mtab", "r");

Isn't it better to use "/proc/mounts" here? Otherwise, if the FS was
mounted using "mount" syscall, then this code will fail to find the
correct mount root.

> +       while ((ent = getmntent(mnttab))) {
> +               len = strlen(ent->mnt_dir);
> +               if (strncmp(ent->mnt_dir, path, len) == 0) {
> +                       /* match found */
> +                       if (longest_matchlen < len) {
> +                               free(longest_match);
> +                               longest_matchlen = len;
> +                               longest_match = strdup(ent->mnt_dir);

Alex.
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/cmds-send.c b/cmds-send.c
index 8a0c110..41ea523 100644
--- a/cmds-send.c
+++ b/cmds-send.c
@@ -28,6 +28,7 @@ 
 #include <sys/types.h>
 #include <sys/ioctl.h>
 #include <libgen.h>
+#include <mntent.h>
 
 #include <uuid/uuid.h>
 
@@ -55,82 +56,35 @@  struct btrfs_send {
 
 int find_mount_root(const char *path, char **mount_root)
 {
-	int ret;
-	char *cur;
-	char fsid[BTRFS_FSID_SIZE];
+	FILE *mnttab;
 	int fd;
-	struct stat st;
-	char *tmp;
-	char *dup = NULL;
-
-	struct btrfs_ioctl_fs_info_args args;
+	struct mntent *ent;
+	int len;
+	int longest_matchlen = 0;
+	char *longest_match = NULL;
 
 	fd = open(path, O_RDONLY | O_NOATIME);
-	if (fd < 0) {
-		ret = -errno;
-		goto out;
-	}
-
-	ret = fstat(fd, &st);
-	if (fd < 0) {
-		ret = -errno;
-		goto out;
-	}
-	if (!S_ISDIR(st.st_mode)) {
-		ret = -ENOTDIR;
-		goto out;
-	}
-
-	ret = ioctl(fd, BTRFS_IOC_FS_INFO, &args);
-	if (fd < 0) {
-		ret = -errno;
-		goto out;
-	}
-	memcpy(fsid, args.fsid, BTRFS_FSID_SIZE);
+	if (fd < 0)
+		return -errno;
 	close(fd);
-	fd = -1;
 
-	cur = strdup(path);
-
-	while (1) {
-		dup = strdup(cur);
-		tmp = dirname(dup);
-
-		if (!tmp)
-			break;
-		fd = open(tmp, O_RDONLY | O_NOATIME);
-		if (fd < 0) {
-			ret = -errno;
-			goto out;
+	mnttab = fopen("/etc/mtab", "r");
+	while ((ent = getmntent(mnttab))) {
+		len = strlen(ent->mnt_dir);
+		if (strncmp(ent->mnt_dir, path, len) == 0) {
+			/* match found */
+			if (longest_matchlen < len) {
+				free(longest_match);
+				longest_matchlen = len;
+				longest_match = strdup(ent->mnt_dir);
+			}
 		}
-
-		ret = ioctl(fd, BTRFS_IOC_FS_INFO, &args);
-		close(fd);
-		fd = -1;
-		if (ret < 0)
-			break;
-		if (memcmp(fsid, args.fsid, BTRFS_FSID_SIZE) != 0)
-			break;
-
-		free(cur);
-		cur = strdup(tmp);
-		free(dup);
-		dup = NULL;
-		if (strcmp(cur, "/") == 0)
-			break;
-		if (strcmp(cur, ".") == 0)
-			break;
 	}
 
-	ret = 0;
-	*mount_root = realpath(cur, NULL);
+	*mount_root = realpath(longest_match, NULL);
+	free(longest_match);
 
-out:
-	if (dup)
-		free(dup);
-	if (fd != -1)
-		close(fd);
-	return ret;
+	return 0;
 }
 
 static int get_root_id(struct btrfs_send *s, const char *path, u64 *root_id)