-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi all and happy new year.

this is my first patch of the new year. Hooping that this is a good
sign. :-)

The enclosed patch try to address the problem raised by Justin: how
circumvent the check performed by mkfs.btrfs ?
I add a "-f|--force" switch which permits to bypass the check if a
device is already mounted. I update the man page too.

You can pull the change from

        http://cassiopea.homelinux.net/git/btrfs-progs-unstable.git

branch

        force-mkfs

commit (2900a150cde604f82f1437c931792bfa59c4780b)

Comments are welcome
Regards
G.Baroncelli

- -- 
gpg key: Goffredo Baroncelli (ghigo) <kreij...@inwind.it>
Key fingerprint = 4769 7E51 5293 D36C 814E  C054 BF04 F161 3DC5 0512



On 01/03/2011 12:14 AM, Goffredo Baroncelli wrote:
> On 01/02/2011 08:52 PM, J G wrote:
>> I just encountered some odd behavior from mkbtrfs.
>> The end goal is to restore a backup to newly created BTRFS partitions while 
>> using the latest btrfs-tools. 
>> Here's the steps to what I did:
>> * Booted SystemRescueCD
>> * Partitioned the drives (two 750GB drives with 12 partitions each)
>> * Created an extra partition on sda as a temporary holding place for the 
>> backed up files and so I can update btrfs-tools
>> * Formatted/mounted/restored backup files to the temporary partition which I 
>> mounted on /mnt/backup
>> * mount -t proc none /mnt/backup/proc; mount -o bind /dev /mnt/backup/dev
>> * chroot /mnt/backup /bin/bash
>> * Updated btrfs-tools to the latest git pull from today 
>> (v0.19-35-g1b444cd-dirty).
>> * mkbtrfs /dev/sda5 /dev/sdb5 -L root
>>
>> mkbtrfs returned with:
>>
>> error checking /dev/sda5 mount status
>>
>> So I used strace to find out how it was checking for the mount status. Now, 
>> I'm no expert here, but I'm confused as to just why it failed. The last 
>> thing of note:
>>
>> lstat("/boot", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
>> lstat("/boot/sysrcd.dat", 0x7fffb29681e0) = -1 ENOENT (No such file or 
>> directory)
>> close(3)                                = 0
>> munmap(0x7f11df372000, 4096)            = 0
>> write(2, "error checking /dev/sda5 mount s"..., 38error checking /dev/sda5 
>> mount status
>> ) = 38
>>
>>
>> doesn't explain much. I see that it's checking /proc/mounts to see what's 
>> mounted, and then it fails on stating /boot/sysrcd.dat (which doesn't exist 
>> in the non-chrooted FS, btw).
>>
>> To make this even weirder, if I format sda5/sdb5 using the SysRescCD version 
>> of mkbtrfs (v0.19) and then format sda5/sdb5 using the chroot version, it 
>> works fine.
>>
>> Any ideas here? I would expect that mkbtrfs would work inside of a chroot 
>> without any assistance from the original root.
>>
>> I have the full strace from the chrooted mkbtrfs failing and from it 
>> succeeding, if that's helpful.
> 
> On the basis of the provided information, and on the code it seems that
> mkfs.btrfs tries hard to check that the user is not formatting a mounted
> disk (or loop). So mkfs.btrfs scan the /proc/mount file and checks every
> devices. To do the check it needs to access the original file if this is
> a "loop backend". This is reasonable.
> 
> In this case in a chroot-ed environment the loop file is not accessible.
> 
> If you need a [dirty] "quick hack" to by-pass the problem (not tested):
> - unmount the proc filesystem
> - create an empty file /proc/mounts
> - run btrfs.fsck
> - mount the proc filesystem (removing the fake mounts file)
> - perform a "btrfs device scan"
> - mount the filesystem
> 
> Of course the "right" solution is to add a "--force" switch which
> permits to by-pass these checks. Other mkfs.* tools have this switch.
> 
>>From the mkfs.ext4 man page:
> [...]
>        -F     Force mke2fs to create a filesystem,
>               even if the specified device is  not
>               a   partition  on  a  block  special
>               device, or if  other  parameters  do
>               not  make  sense.  In order to force
>               mke2fs to create a  filesystem  even
>               if  the  filesystem appears to be in
>               use or is mounted (a truly dangerous
>               thing  to  do),  this option must be
>               specified twice.
> 
> [...]
> 
> 
>>
>> .:Justin:.
>>
>>
>>       
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
>> the body of a message to majord...@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 majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> .
> 

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iD8DBQFNIh34vwTxYT3FBRIRAl1tAJ9k1LVUfahdlvLvK7b4gct55fom3QCfd1Ab
0JfVbWgKf7DXd0Gg1YzaPdU=
=Jt+e
-----END PGP SIGNATURE-----
diff --git a/man/mkfs.btrfs.8.in b/man/mkfs.btrfs.8.in
index 1e14c6c..f51291c 100644
--- a/man/mkfs.btrfs.8.in
+++ b/man/mkfs.btrfs.8.in
@@ -5,14 +5,14 @@ mkfs.btrfs \- create an btrfs filesystem
 .B mkfs.btrfs
 [ \fB\-A\fP\fI alloc-start\fP ]
 [ \fB\-b\fP\fI byte-count\fP ]
-[ \fB \-d\fP\fI data-profile\fP ]
-[ \fB \-l\fP\fI leafsize\fP ]
-[ \fB \-L\fP\fI label\fP ]
-[ \fB \-m\fP\fI metadata profile\fP ]
-[ \fB \-n\fP\fI nodesize\fP ]
-[ \fB \-s\fP\fI sectorsize\fP ]
-[ \fB \-h\fP ]
-[ \fB \-V\fP ] \fI device\fP [ \fI device ...\fP ]
+[ \fB\-d\fP\fI data-profile\fP ]
+[ \fB\-f\fP ]
+[ \fB\-l\fP\fI leafsize\fP ]
+[ \fB\-L\fP\fI label\fP ]
+[ \fB\-m\fP\fI metadata profile\fP ]
+[ \fB\-n\fP\fI nodesize\fP ]
+[ \fB\-s\fP\fI sectorsize\fP ]
+[ \fB\-V\fP ] \fIdevice\fP [ \fIdevice ...\fP ]
 .SH DESCRIPTION
 .B mkfs.btrfs
 is used to create an btrfs filesystem (usually in a disk partition, or an array
@@ -34,6 +34,9 @@ mkfs.btrfs uses all the available storage for the filesystem.
 Specify how the data must be spanned across the devices specified. Valid
 values are raid0, raid1, raid10 or single.
 .TP
+\fB\-f\fR, \fB\-\-force \fR
+Don't check if the device is already mounted.
+.TP
 \fB\-l\fR, \fB\-\-leafsize \fIsize\fR
 Specify the leaf size, the least data item in which btrfs stores data. The
 default value is the page size.
diff --git a/mkfs.c b/mkfs.c
index 2e99b95..21bcc7a 100644
--- a/mkfs.c
+++ b/mkfs.c
@@ -271,6 +271,7 @@ static void print_usage(void)
 	fprintf(stderr, "\t -A --alloc-start the offset to start the FS\n");
 	fprintf(stderr, "\t -b --byte-count total number of bytes in the FS\n");
 	fprintf(stderr, "\t -d --data data profile, raid0, raid1, raid10 or single\n");
+	fprintf(stderr, "\t -f --force don't check if a device is already mounted\n");
 	fprintf(stderr, "\t -l --leafsize size of btree leaves\n");
 	fprintf(stderr, "\t -L --label set a label\n");
 	fprintf(stderr, "\t -m --metadata metadata profile, values like data profile\n");
@@ -332,6 +333,7 @@ static struct option long_options[] = {
 	{ "sectorsize", 1, NULL, 's' },
 	{ "data", 1, NULL, 'd' },
 	{ "version", 0, NULL, 'V' },
+	{ "force", 0, NULL, 'f' },
 	{ 0, 0, 0, 0}
 };
 
@@ -358,10 +360,11 @@ int main(int ac, char **av)
 	int first_fd;
 	int ret;
 	int i;
+	int force=0;
 
 	while(1) {
 		int c;
-		c = getopt_long(ac, av, "A:b:l:n:s:m:d:L:V", long_options,
+		c = getopt_long(ac, av, "A:b:l:n:s:m:d:L:Vf", long_options,
 				&option_index);
 		if (c < 0)
 			break;
@@ -401,6 +404,9 @@ int main(int ac, char **av)
 			case 'V':
 				print_version();
 				break;
+			case 'f':
+				force=1;
+				break;
 			default:
 				print_usage();
 		}
@@ -423,13 +429,16 @@ int main(int ac, char **av)
 
 	file = av[optind++];
 	ret = check_mounted(file);
-	if (ret < 0) {
-		fprintf(stderr, "error checking %s mount status\n", file);
-		exit(1);
-	}
-	if (ret == 1) {
-		fprintf(stderr, "%s is mounted\n", file);
-		exit(1);
+	if(!force){
+		if (ret < 0) {
+			fprintf(stderr, "error checking %s mount status\n", 
+				file);
+			exit(1);
+		}
+		if (ret == 1) {	
+			fprintf(stderr, "%s is mounted\n", file);
+			exit(1);
+		}
 	}
 	ac--;
 	fd = open(file, O_RDWR);
@@ -479,15 +488,17 @@ int main(int ac, char **av)
 	zero_end = 1;
 	while(ac-- > 0) {
 		file = av[optind++];
-		ret = check_mounted(file);
-		if (ret < 0) {
-			fprintf(stderr, "error checking %s mount status\n",
-				file);
-			exit(1);
-		}
-		if (ret == 1) {
-			fprintf(stderr, "%s is mounted\n", file);
-			exit(1);
+		if(!force){
+			ret = check_mounted(file);
+			if (ret < 0) {
+				fprintf(stderr, "error checking %s"
+					" mount status\n",file);
+				exit(1);
+			}
+			if (ret == 1) {
+				fprintf(stderr, "%s is mounted\n", file);
+				exit(1);
+			}
 		}
 		fd = open(file, O_RDWR);
 		if (fd < 0) {

Attachment: mkfs.btrfs-force.diff.sig
Description: PGP signature

Reply via email to